As far as I know the only way to get the midpoint of a curve is to use curve.PointAtLength(curve.GetLength() / 2), correct - at least this is what I do.
Would it maybe make sense to add a property to the Curve class, e.g. PointAtMid? At least for me it would save a lot of typing. Even though I could build a small method in my toolbox I always think it would be faster to have this in RhinoCommon and wonder why this is not available there.
As distance is normalized [0, 1] you MUST use 0.5 to be on the middle.
curve.PointAtNormalizedLength(0.5);
But yes something like
curve.PointAtMiddle;
could make sense, as it was done in Grasshopper.
Long time ago there was just tha component. It that was quite hard to discover, I found it after some months!
And as it was quite just used for special case they added this one.
@laurent_delrieu
Allright, I have to admit I did understand PointAtNormalizedLength quite the wrong way. But I am relieved because it makes me sleep better
I also came across the grasshopper component quite late and that acutally was the reason I always wondered if there is an equivalent in RhinoCommon.
import Rhino
import scriptcontext as sc
def __normalized_pointat(curve, s):
pt = Rhino.Geometry.Point3d.Unset
if curve and s >= 0.0 and s <= 1.0:
rc, t = curve.NormalizedLengthParameter(s)
if rc:
pt = curve.PointAt(t)
return pt
def test_curve_midpoint():
filter = Rhino.DocObjects.ObjectType.Curve
rc, objref = Rhino.Input.RhinoGet.GetOneObject("Select curve", False, filter)
if not objref or rc != Rhino.Commands.Result.Success:
return
curve = objref.Curve()
if not curve:
return
# start point
pt = __normalized_pointat(curve, 0.0)
if pt.IsValid:
sc.doc.Objects.AddPoint(pt)
# mid point
pt = __normalized_pointat(curve, 0.5)
if pt.IsValid:
sc.doc.Objects.AddPoint(pt)
# end point
if not curve.IsClosed:
pt = __normalized_pointat(curve, 1.0)
if pt.IsValid:
sc.doc.Objects.AddPoint(pt)
sc.doc.Views.Redraw()
if __name__ == "__main__":
test_curve_midpoint()