Double-Click Within Text Area to Select ALL Code
/* ########################################################################### This function computes the perimeter of an ellipse or elliptical orbit with the given parameters (R, r). It is a high-precision, brute-force numerical solution to the complete elliptic integral of the second kind. Where: r = Semiminor axis R = Semimajor axis C = Circumference of Ellipse (r, R) can be in any convenient units, such as AUs, kilometers, miles, etc. Internally, arbitrary-precision arithmetic is used to help preserve accuracy, with the final result rounded at 16 decimals. NOTE: Since this function uses BC arithmetic, the numeric values used should be numeric strings, like '3210.123465978' to represent EXACT values and to avoid confusion with the default fixed double-precision numbers. Author : Jay Tanner - 2026 ########################################################################### */ function Ellipse_Circum ($RParam='1', $rParam='1') { // ----------------------------------------------- // Read input (R, r) ellipse parameter arguments. // they are assumed to be purely numeric strings. $R = trim($RParam); // Corresponds to (a) $r = trim($rParam); // Corresponds to (b) // ----------------------------------------------------- // Return FALSE (ERROR) if either (R, r) is non-numeric. if (!Is_Numeric($R) or !Is_Numeric($r)) {return FALSE;} // -------------------------------------------- // Define local constant (2*pi) to 50 decimals. $TwoPi = '6.28318530717958647692528676655900576839433879875'; // ------------------------------------------ // Set to 16 decimals final output precision. $decimals = 16; /* ---------------------------------------------- Use 8 extra decimals for internal computations to reduce accumulative rounding errors in the final summation. */ $d = $decimals + 8; // --------------------------------------------- // If (r > R), then swap values so that (R > r). if (bcComp($R, $r, $d) < 0) {$w=$R; $R=$r; $r=$w;} // ------------------------------------------------------ // Compute the square of the elliptic eccentricity value. $e2 = bcSub('1', bcDiv(bcMul($r,$r,$d), bcMul($R,$R,$d),$d),$d); /* ------------------------------------------------- Perform power series summation loop while the nth term is > the 16-decimal (PrecisionLimit). This limit could be changed, but 16 decimals should generally be sufficient. */ $n = $ePow2n = $PrecisionLevel = 1; $sum = 0; $PrecisionLimit = '0.' . Str_Repeat('0', $d-1) . '1'; while (abs($PrecisionLevel) > $PrecisionLimit) { $N = 2*$n - 1; $X = 1; for ($n=0; $n <= ceil($N/2)-1; $n++) { $X = bcMul($X, $N - 2*$n); // (2n-1)!! } $X2 = bcMul($X,$X); // (2n-1)!!^2 $N = 2*$n; $Y = 1; for ($n=0; $n <= ceil($N/2)-1; $n++) { $Y = bcMul($Y, $N - 2*$n); // (2n)!! } $Y2 = bcMul($Y,$Y); // (2n)!!^2 $ePow2n = bcMul($ePow2n, $e2, $d); // e^(2n) $Numer = bcMul($X2, $ePow2n, $d); // (2n-1)!!^2 * e^(2n) $Denom = bcMul($Y2, 2*$n - 1, $d); // (2n)!!^2 * (2n-1) $CurrSumTerm = bcDiv($Numer, $Denom, $d); $sum = bcAdd($sum, $CurrSumTerm, $d); $PrecisionLevel = bcSub($CurrSumTerm, $PrecisionLimit, $d); $n++; } // END OF while (...) /* ------------------------------------------------- The summation part is done. Finish computing the final elliptic circumference and round the result to the indicated number of decimals. */ $C = bcMul($TwoPi, bcMul($R, bcSub('1', $sum, $d),$d),$d); return bcAdd($C, '0.'.str_repeat('0', $decimals).'5', $decimals); } // END OF Ellipse_Circum (...)