Nasty Nurb - When is a straight line not a straight line?

Good Morning,

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?

image

Hi,
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.

Hope that helps,
Farouk

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.

Thanks @Gijs Any idea idea why the Convert ToArcsAndLines method fails when the line is in one location and succeeds when it is moved slightly?

I don’t really know what is happening with that curve, but ToArcsAndLines doesn’t give a useable result with this curve anyway.
Is this part of a bigger problem?

1 Like

this somehow looks buggy to me.
_fitCrv with tolerance 0.001 , degree 3 shoots into something useless:

blue input
red _fitCrv

1 Like

Thanks @Gijs and @Tom_P

I think you have hit the nail on the head - do you have any idea how i can isolate what is wrong or dubious with this particular curve?

Are we thinking there is a bug in FitCrv and ToArcsAndLines?

This is part of our CNC program, it sucessfully handles tens of thousands of curves a day, i am quite intriuged to know what is dubious with this specific curve.

as @farouk.serragedine shows there are manual tools to fix it but i will need to find something automatic.

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

1 Like

Maybe I was not very clear, sorry about that, what I meant in my first message :

"It’s a simple problem, the curve cannot be converted to line because It’s not a line, so you make it into a line by rebuilding it so that it is a planar line defined by 2points and no curvature, or you draw a new line using the appropriate rhinocommon methods.
https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.curve/rebuild?version=8.x
https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.curve?version=8.x
https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.curve/getdistancesbetweencurves?version=8.x

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 :

  1. take the nurbs curve
  2. take the start and end points
  3. add new curve
  4. compare the distance between newcurve and old curve
  5. if maxgap<tollerance gg you did it

In case I missed your question I’ll let someone else intervene.
Hope that helps."

@Joshua_Kennedy now I looked at the code you linked …

what interests me most:
what s the concept of the number of testpoints ?

n = 2*span_degree+1;

less important:
and I also don t understand why the for loop is continued after it turned false ?

rc = false;

instead of

return false;

thanks

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 ?

Thank you @Joshua_Kennedy that’s very helpful :slightly_smiling_face:

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.

alright with much thanks to @Joshua_Kennedy & @Tom_P I have a workaround for these nasty nurbs curves.

For Curves which are Beziers but which fail ALL of the following API checks:

  • ToArcsAndLines
  • IsLinear (nurbs)
  • TryGetArc
  • TryGetPolyLine

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 :slight_smile:

So i think I have a solution :slight_smile: Thanks All

I think both ToArcsAndLines and IsLinear would benefit from a tune up to handle curves like these with stacked control points.

1 Like

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.

Neither do I

1 Like

NurbsCurvePointList.ValidateSpacing might help. I’d also be curious about how that curve got made. A curve can be bad to the point its worth not trying to handle.

1 Like

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.

1 Like