private bool NewtonSearch( BsplineCurve curve, double chord, ref double param, ref Point3d result, double tolerance = 0.0001) { //-- Start Point //-- var start = curve.EvaluatePoint( param ); //-- Initial Guess: Blind Forward //-- param += 0.1; while( ( param >= 0.0 ) && ( param <= 1.0 ) ) { //-- Evaluate Point //-- result = curve.EvaluatePoint( param ); var distance = MSApp.Point3dDistance( ref start, ref result ) - chord; if( Math.Abs( distance ) < tolerance ) return true; //#debug { AddLine( start, result ); } //#enddebug //-- Newton Raphson Improved Guess //-- f'(t) = (f(t+h) - f(t)) / h var point = curve.EvaluatePoint( param + tolerance ); var delta = ( MSApp.Point3dDistance( ref start, ref point ) - ( distance + chord ) ) / tolerance; param -= distance / delta; } return false; }
//-- Biforcation/Branching Solver //-- //-- private bool BranchSearch( BsplineCurve curve, double chord, ref double param, ref Point3d result, double tolerance = 0.0001) { //-- Evaluate Start Point //-- var start = curve.EvaluatePoint( param ); //-- Search Between [Curve.start, Curve.Max] //-- var min = param; var max = 1.0; while( ( max - min ) > tolerance ) { //-- Evaluate Mid-Point //-- param = 0.5 * ( min + max ); result = curve.EvaluatePoint( param ); //-- Found within Tolerance? //-- var distance = MSApp.Point3dDistance( ref start, ref result ); if( Math.Abs( distance - chord ) < tolerance ) return true; //#debug { AddLine( start, result ); } //#enddebug //-- Select Half-Span //-- if( distance < chord ) min = param; else max = param; } //-- End Point Reached //-- return false; }
//-- Brute force-ish //-- private bool MarchSearch( BsplineCurve curve, double chord, ref double param, ref Point3d result, double tolerance = 0.0001) { //-- Evaluate Start Point //-- var start = curve.EvaluatePoint( param ); //-- Make step size assumption //-- var step = 0.1; while( ( param >= 0.0 ) && ( param <= 1.0 ) ) { //-- Next Point //-- param += step; result = curve.EvaluatePoint( param ); //-- Found within Tolerance? //-- var distance = MSApp.Point3dDistance( ref start, ref result ); if( Math.Abs( distance - chord ) < tolerance ) return true; //#debug { AddLine( start, result ); } //#enddebug //-- Overshoot -> Switch Direction + Half Step //-- if( ( ( step > 0 ) && ( distance > chord ) ) || ( ( step < 0 ) && ( distance < chord ) ) ) step *= -0.5; } return false; }