Hi,
I have a recursive bit of c# code to turn a Curve into a polyline with a set distance tolerance:
void SubdivideRecursive(Curve crv, double dMinT, double dMaxT, double dTol)
{
LineCurve line = new LineCurve(crv.PointAt(dMinT), crv.PointAt(dMaxT));
double dMidParam = (dMinT + dMaxT) / 2.0;
Curve.GetDistancesBetweenCurves(crv, line, 0.1, out double maxdis, out _, out _, out _, out _, out _);
if (maxdis > dTol)
{
SubdivideRecursive(crv, dMinT, dMidParam, dTol);
SubdivideRecursive(crv, dMidParam, dMaxT, dTol);
}
else
{
recursiveOuput.Add(line);
}
}
The code works fine but I’m using it for XL format 3d printing so the inputs are very large. What I’d like to know is if there’s any version of the GetDistancesBetweenCurves where the output is the squared result to speed up calculations. As you can also see I’m only using the furthest distance to calculate if the code should continue, so could also use a much stripped back method if one exists.
I’ve forgotten whose algorithm this is, if you know, I’ll update to make sure its credited.
I’ve had a look through the forums and haven’t found this brought up, apologies if I’ve missed a thread.
Hello,
if I understand correctly, your code does this:
I’m not sure how squaring the deviation would help.
Maybe you could precompute a good estimate of a polyline using Curve.ToPolyline method. It only checks the deviation at line midpoint, so it should be faster. Then you can go back and refine each line segment using your algorithm.
Curve.ToPolyline method (rhino3d.com)
Hey Vojtech,
Some libraries like Unity have distance squared methods, which can be a bit confusing as its really just the formula absent the root function = your tolerance squared.
In other words you go from this
d = √(x2 - x1)2 + (y2 - y1)2
to this
d2 = (x2 - x1)2 + (y2 - y1)2
which runs a lot quicker. Rhino doesn’t seem to have this option for its distances so I usually write my own, but I’m nowhere near clever enough to figure out how to find the closest or furthest point between curves. I’ve seen a few tutorials online but it seems there’s a lot of conditions and variations you’d have to consider.
precomputing isn’t a bad idea, although if I’m checking the segments anyway I don’t know how much quicker it’ll run. Worth a play around.
In other words you go from this
d = √(x2 - x1)2 + (y2 - y1)2
to this
d2 = (x2 - x1)2 + (y2 - y1)2
Silly me, this should have been obvious.
That’s (in general) a classic Bounce Solver problem. I.e. start from some value (that yiels some result), compare the result VS a target result and either accept the result or grow/srink the value (using a step value) until the result is achieved. Each time a switch (from grow to strink or the other way) event occurs divide step by 2.0 and multiply step by -1;.
Given a targetDist, a step value and a Curve crv (with Domain 0-1), start from a value t that Splits (from 0 to t) the crv into a segment . Then get the Line from start/end segment pts and find the max dist (using an oriented Box where Plane’s X dir is the line direction and Y Dir is the cross product [direction, global z)). If Math.Abs ( dist - tol) < targetDist get the Line, split the Crv (from t to 1) and continue. If not grow/srink t (by step) while reduce step to half each time a swap accurs.
Obviously (general) case get the Curve segments (if any) and if some are Linear (to some tol) … do whatever you want (accept/reject).
Notify if you want an indicative C# as an intro to Bounce Solvers.