protected double SolveNewton( double a, double b, out int _IterationsCount )
{
if ( a > 1.0 )
a = 1.0 / a; // Mirror to avoid badly formed equations... (the scale factor is symmetric anyway)
// Compute the original intersection of the straight line of slope tan( ThetaH0 / ThetaD0 ) with the line ThetaD = PI/2
double OriginalThetaH = 0.5 * Math.PI;
double OriginalThetaD = 0.5 * Math.PI * a; // ThetaD_without_intersection = PI/2 * slope
double OriginalSqLength = OriginalThetaD*OriginalThetaD + OriginalThetaH*OriginalThetaH;
// Start from 0 and iterate
double x = 0.499999 * Math.PI; // Start from nearby PI/2 where the function is ill defined but will converge quickly
double Value = Math.Tan(a*x) * Math.Tan(x) - b;
_IterationsCount = 0;
bool bError = false;
while ( Value > 1e-4 )
{
_IterationsCount++;
// Compute the step we need to perform...
double Derivative = a * Math.Tan(x) / (Math.Cos(a * x) * Math.Cos(a * x)) + Math.Tan(a * x) / (Math.Cos(x)*Math.Cos(x));
if ( Math.Abs( Derivative ) < 1e-10 )
{ // Can't go on!
bError = true;
break;
}
double Step = Value / Derivative;
x -= Step;
// Estimate new error...
double OldValue = Value;
Value = Math.Tan(a*x) * Math.Tan(x) - b;
double ErrorDiff = OldValue - Value;
if ( ErrorDiff < 1e-4 )
{ // Seems to be either static or divergent... There is no obvious solution but we'll accept the current value anyway...
bError = true;
break;
}
}
double IntersectionThetaH = Math.Min( 0.5 * Math.PI, x );
double IntersectionThetaD = a * IntersectionThetaH;
double IntersectionSqLength = IntersectionThetaH*IntersectionThetaH + IntersectionThetaD*IntersectionThetaD;
double ScaleFactor = Math.Sqrt( IntersectionSqLength / OriginalSqLength );
if ( ScaleFactor > 1.0 || bError )
throw new Exception( "Crap!" );
// ScaleFactor = Math.Min( 1.0, ScaleFactor * 1.1 );
ScaleFactor = ScaleFactor * floatTrackbarControlScaleFactor.Value;
return ScaleFactor;
}