(C++ SDK) ON_Curve::PointAT returns inconsistent results

I get a curve then find the domain with ON_Curve::GetDomain(*t0, *t1).
I then add a point to the document that is located 3/4 of the way though the domain using the PointAt method.
doc->AddPointObject(MyCurve->PointAt(t0 + (t1 - t0) * 0.75));
The results for 3 curves are shown below.

The first curve is a single straight line with the added point shown 3/4 of the way along the line in model space.
The next line is a polyline with 2 segments created with the Rhino “_Lines” command. The mouse points used for selection of the ends are shown with an “x”. The returned point is consistent with the first line.
The third line is the same as the second except it was created from 2 individual lines with the Rhino “_Join” command. The returned point is different.
Shouldn’t all these lines return consistent point locations?

No, it all depends on how the knot values are distributed, and where the control points are located. If you want to get a consistent length along an arbitrary curve, you should use the following:

ON_Curve crv; // defined elsewhere

double t;
ON_3dPoint pt(ON_3dPoint::UnsetPoint);
if (crv->GetNormalizedArcLengthPoint(0.75, &t))
    point = crv->PointAt(t);

In your right-most example, the bottom line has the domain [0…1] and the top line has [1…2]. Therefore the point at 3/4 the domain of [0…2] is at 1.5, which is the middle of the top line.

Hello Menno:
Thanks for your response.
Yes, the domains for the 2 curves are different, but only because of the _Join operation. The curve I show in the middle was created by what I should have said was the _Polyline command.(Not _Lines) If you explode this polyline, you will see the 2 segments have a good parameterization with a domain range having some correlation to the segment length. Rhino doesn’t normalize the domains for numerical reasons. The curve on the right was created from two separate segments, identical to the previous curve, then manually joined. If you look at these 2 segments before joining, you will see their domains are equivalent to the previous good ones. The _Join command for some reason throws away these good domains and replaces them with normalized ones instead of respecting them like the _Polyline command does when it joins the segments.

Sorry, I can’t comment on the inner workings of Join vs. Polyline ; maybe a McNeel person can.

Hi @Gary,

Can you post your geometry and clearly identify how each curve as created?


– Dale


The geometry consists of the blue curves posted above. The 2 curves on the right are straight polylines created by the user in the document with the segment end points indicated by an “x”. The 2 polylines each consist of 2 segments. The only difference between the first polyline and the second one is that the first one was created by the “_Polyline” command which automatically joins the segments and for the second polyline the user explicitly called the “_Join” command to connect the segments.


I’d rather see your file, if you don’t mind.

– Dale


Polylines.3dm (25.0 KB)

Hi @Gary,

The Join command isn’t doing anything special with the domain when joining line segments into a polyline curve. The domain is simply set to [0.0, SegmentCount], which is the default when constructing new polyline curves.

Hope this helps.

– Dale

Hi Dale:

I don’t understand how you can say that the normalized domain method is the default when constructing new polylines. As I discussed above, the _Polyline command is another way to construct a new polyline, and it doesn’t join the segments together in a way that is consistent with the _Join command method. The _Polyline command doesn’t normalize the segments like the so called default way. Normalized domains for individual linear lines may be just fine but when you combine the lines together into a ployline, it is useful to use a more intelligent parameterization like the _Polyline command uses. It allows for a more efficient way to do point evaluations because you don’t have to call GetNormalizedArcLengthPoint() each and every time you want to do an evaluation.


Hi @Gary,

What I am saying is that the constructor for ON_PolylineCurve sets the domain differently than that of the Polyline command, which after constructing a new ON_PolylineCurve, explicitly set the curve to use arc length parameterization.

I’ve added a wish to the pile to make the two tools do the same thing.


– Dale