I’m looking for a bit of advice with this Nurb - it is essentially a straight line - indeed I can rebuild it with 2 controlpoints and find maximum deviation of 0.000164465.
However when i call Curve.ToArcsAndLines method (rhino3d.com)
I get a null result unless i increase my tolerance as high as 0.02 - so for example ToArcsAndLines(0.01,0.0174532925199433,0.01,10000000) fails.
Can anyone see what is “special” or “wrong” with this geometry to cause it to fail? Is it something to do with the control points being so close together? Is there a way to fix/clean that?
I note that if i move the geometry in X or Y the conversion suddenly starts succeeding with very low tolerances. badNurb.3dm (27.0 KB)
I am also experiancing this in both Rhino 7 and Rhino 8.
Are there other tools i can use to convert this Nurb to a line?
A line is a straight by definition, which means it has 2 points, starting point, endpoint .(it can be described by more than 2 points, but that’s inefficient design).
It means you’re trying to make something that is not “straight” according to the above definition, straight. Cause you are trying to make it into a line.
What to do : Rebuild the curve or draw a new curve based on start/endpoint
Increasing tollerance will work because It will ignore how curved it is, so much that at a certain point within that tollerance It results as a line.
When connecting a polyline through the control points of this curve, the angle between the two lines is 0.271 degrees, so I’d say this is far from being a straight line, even though the absolute distance between this curve and a straight line is small.
The ON_NurbsCurve::IsLinear check fails for me here with the document tolerance
Those CVs are nearly stacked at the end points so the failure makes sense given the comment. You can always fit a line through the curves start/end point then sample the curve and check the distance from the line. If it’s all less than tolerance you can call it linear. The ON_Curve::IsLinear check works similarly
You can refit it according to your tollerance and make it actually a line.
Maybe I don’t understand your question, if the issue is just that you’re trying to convert a nurbs curve into a straight line It should be very straightforward.
To be even more clear :
take the nurbs curve
take the start and end points
add new curve
compare the distance between newcurve and old curve
if maxgap<tollerance gg you did it
In case I missed your question I’ll let someone else intervene.
Hope that helps."
replace the curve with a line.
mark it with a dot.
ask the customer to inspect the potential error and send the unconverted curve / file to you ?
if this case pops up once per year - … nothing more to do ?
Funnily enough the very next line is a call to ON_NurbsCurve::IsLinear which as you say fails. I never reached it because Curve.ToArcsAndLines returns null.
It suprised me that ON_NurbsCurve::IsLinear and Curve.IsLinear take different approaches though i suppose it should’t as NurbsCurves are a different kettle of fish.
So i think at root problem here is the repeated coincident control points on the ends of curve.
@Tom_P the challenge remains efficiently detecting this problem - I am not keen to have to test every curve with a newly generated straight line because IsLinear fails when controlpoint are co-incident on 1 curve in 100,000. I have had 3 files exhibiting several cases of this problem so far this week.
For Curves which are Beziers but which fail ALL of the following API checks:
I conduct a manual test against a newly constructed straight line from PointatStart to PointAtEnd. I hope that will limit the cases and make for efficent code. Thanks @farouk.serragedine for the hint about GetDistancesBetweenCurves I didn’t know it calculates the maximum as well
So i think I have a solution Thanks All
I think both ToArcsAndLines and IsLinear would benefit from a tune up to handle curves like these with stacked control points.
I see that and similar scattered all around in Rhino. There’s another example here when checking if a curve is on a surface
Basically, when checking if something is within tolerance/lies on surface/is linear the best/only way to do it is sample many points and check. Hardcoding some number like 100 that may be too dense than necessary for some cases and not dense enough for others. That expression gets you in the right neighborhood without sampling too much since closest point calls can be expensive.
Just in case anyone else encounters such horrible geometry, the solution was to use the NurbsCurvePointList.ValidateSpacing method suggested by @Joshua_Kennedy and to delete the nurbs curve and re-create without the identified stacked control points. Two complications were to avoid deleting the last point so that the domain of the curve is unchanged and to watch for the degree of the curve changing.
All the examples of this behaviour i had were on “straight” lines with two control points placed very close at each end. I have yet to encounter this issue to a true “curve” of higher degree.