Boom! I was going in the same direction, approaching it in a simple (but hard to implement) binary search, but you shot at the target!
Thanks, well done!
I converted it to a C# component here, to keep us in an faster arena (is faster to make a script in GH than to compile a plugin):
PointAtEuclidianLength-CodeChallenge.gh (23.2 KB)
The EstimateParameterTolerance() function I don’t quite understand it. I get that it serves to stop searching if the search domain is below that threshold, but I don’t know why that formula.
Do you have any idea how to automate the bias to speed up the search? No need, just out of curiosity.
I don't know if I'll ever use it, I want to explore some things, but do I have your permission to include the following function in the Peacock library that will be my Github someday?
public static double ParameterAtEuclidianLength(Curve curve, double position, double length, double tolerance = 1e-12)
// Created by Keyu Gan (@gankeyu) 13 Jun 2020
// reshaped by @Dani_Abalde
var bias = 0.5;
var msLimit = 60000;
var squareDist = length * length;
var lowerBound = position;
var upperBound = curve.Domain.T1;
var origin = curve.PointAt(position);
var sw = new System.Diagnostics.Stopwatch();
var middleGround = (upperBound - lowerBound) * bias + lowerBound;
var delta = (curve.PointAt(middleGround) - origin).SquareLength - squareDist;
var groundLength = upperBound - lowerBound;
if (!RhinoMath.IsValidDouble(groundLength) || groundLength < 1e-16 || sw.ElapsedMilliseconds > msLimit)
middleGround = groundLength * bias + lowerBound;
delta = (curve.PointAt(middleGround) - origin).SquareLength - squareDist;
if (delta > tolerance)
upperBound = middleGround;
else if (delta < -tolerance)
lowerBound = middleGround;
The function above doesn't work as the original one (blue point), this one fails at these cases (green point):
It can be fixed with a low bias, but but this is detrimental to performance.