/* * ------------------------------------------------------ * Application: MathExtensions.as * ------------------------------------------------------ * Version: 2.2 * ------------------------------------------------------ * Latest update: August16, 2003 * Major update, now including 95 Math object extensions * ------------------------------------------------------ * Original compilation by Brandon Williams - Jan 2002 * [brandon@plotdev.com] * Additional compilation by Richard Wright - June 2003 * [wisolution2002@shaw.ca] * ------------------------------------------------------ * Some of these functions are JavaScript ports from: * Oscar van Vlijmen - Jan. 2003 - mailto:ovv@hetnet.nl * Website: http://home.hetnet.nl/~vanadovv/Gonio.html * Eric S. Rowland - April, 2003 - mailto:erowland@ucsc.edu * Website: http://people.ucsc.edu/~erowland/playground.html * ------------------------------------------------------ * Additional contributions from: * Robert Penner - 2001-2002 - mailto:info@robertpenner.com * Website: www.robertpenner.com * ------------------------------------------------------ * Other contributors have been recognized within the code * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of this software nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ------------------------------------------------------ * A synopsis for all of the Math object's constants and * methods, and for all of the Math object extensions' * constants and functions. * ------------------------------------------------------ * Suggestion: When writing code with many Math object * methods/functions, it is desirable to use the 'with' wrapper * for convenience and code optimization: * * with (Math) { * // code here, with no further object reference needed * } * * ------------------------------------------------------ * The following is a list of all core Math object constants and methods, and a * selection of extensions to the Math object containing constants and functions * available for future mathematically-inclined scripts. If you wish to have a * handy list of all the Math object extensions onstage, include Vera Fleischer's * 'traceAlertBox' * component in your .fla with an instance name of 'alert_ta', which will be * recognized by this script to display 'methods_str'. * ------------------------------------------------------ * Updates may be available at: * http://members.shaw.ca/flashmath101/as/ * ------------------------------------------------------ */ methods_str = 'Math Object\n\n'; methods_str += 'Constants\n\n'; methods_str += '1 - E - natural log - Euler\'s number - 2.71828182845905\n'; methods_str += '2 - LN2 - natural log of 2 - 0.69314718055994528623\n'; methods_str += '3 - LN10 - natural log of 10 - 2.3025850929940459011\n'; methods_str += '4 - LOG2E - base 2 of natural log (E) - 1.442695040888963387\n'; methods_str += '5 - LOG10E - base 10 of natural log (E) - 0.43429448190325181667\n'; methods_str += '6 - PI - ratio of circumference to diameter of a circle - 3.14159265358979\n'; methods_str += '7 - SQRT1_2 - squareroot of 1/2 - 0.707106781186\n'; methods_str += '8 - SQRT2 - squareroot of 2 - 1.414213562373\n\n'; methods_str += 'Methods\n\n'; methods_str += '1 - abs(x)\n'; methods_str += '2 - acos(x)\n'; methods_str += '3 - asin(x)\n'; methods_str += '4 - atan(x)\n'; methods_str += '5 - atan2(y,x)\n'; methods_str += '6 - ceil(x)\n'; methods_str += '7 - cos(x)\n'; methods_str += '8 - exp(x)\n'; methods_str += '9 - floor(x)\n'; methods_str += '10 - log(x)\n'; methods_str += '11 - max(x,y)\n'; methods_str += '12 - min(x,y)\n'; methods_str += '13 - pow(x,y)\n'; methods_str += '14 - random()\n'; methods_str += '15 - round(x)\n'; methods_str += '16 - sin(x)\n'; methods_str += '17 - sqrt(x)\n'; methods_str += '18 - tan(x)\n\n'; methods_str += 'Math Object Extensions\n\n'; methods_str += 'Constants\n\n'; methods_str += '1 - DEG2RAD - convert degrees to radians - 0.0174532925199433\n'; methods_str += '2 - RAD2DEG - convert radians to degrees - 57.2957795130823\n'; methods_str += '3 - PHI - the golden mean - 1.61803398874989\n'; methods_str += '4 - LAMBDA - Euler-Mascheroni constant - 0.57721566490143\n\n'; methods_str += 'Trigonometry Extensions\n\n'; methods_str += 'Trig-Decimal Functions\n\n'; methods_str += '1 - sinD(angle) - sin in degrees\n'; methods_str += '2 - cosD(angle) - cos in degrees\n'; methods_str += '3 - tanD(angle) - tan in degrees\n'; methods_str += '4 - asinD(ratio) - asin in degrees\n'; methods_str += '5 - acosD(ratio) - acos in degrees\n'; methods_str += '6 - atanD(ratio) - atan in degrees\n'; methods_str += '7 - atan2D(y,x) - atan2 in degrees\n\n'; methods_str += 'Circle Trigonometric Functions\n\n'; methods_str += '8 - sec(angle) - secant\n'; methods_str += '9 - asec(ratio) - arcsecant\n'; methods_str += '10 - csc(angle) - cosecant\n'; methods_str += '11 - acsc(ratio) - arccoseceant\n'; methods_str += '12 - cot(angle) - cotangent\n'; methods_str += '13 - acot(ratio) - arccotangent\n'; methods_str += '14 - vers(n) - versine\n'; methods_str += '15 - covers(n) - coversine\n'; methods_str += '16 - havers(n) - haversine\n'; methods_str += '17 - cohavers(n) - cohaversine\n'; methods_str += '18 - exsec(n) - exsecant\n'; methods_str += '19 - coexsec(n) - coexsecant\n'; methods_str += '20 - avers(ratio) - arcversine\n'; methods_str += '21 - acovers(n) - arccoversine\n'; methods_str += '22 - ahavers(ratio) - archaversine\n'; methods_str += '23 - aexsec(n) - arcexsecant\n\n'; methods_str += 'Hyperbolic Trigonometric Functions\n\n'; methods_str += '1 - sinh(n) - hyperbolic sine\n'; methods_str += '2 - asinh(n) - hyperbolic arcsine\n'; methods_str += '3 - cosh(n) - hyperbolic cosine\n'; methods_str += '4 - acosh(n) - hyperbolic arccosine\n'; methods_str += '5 - tanh(n) - hyperbolic tangent\n'; methods_str += '6 - atanh(n) - hyperbolic arctangent\n'; methods_str += '7 - sech(n) - hyperbolic secant\n'; methods_str += '8 - asech(n) - hyperbolic arcsecant\n'; methods_str += '9 - csch(n) - hyperbolic cosecant\n'; methods_str += '10 - acsch(n) - hyperbolic arccosecant\n'; methods_str += '11 - coth(n) - hyperbolic cotangent\n'; methods_str += '12 - acoth(n) - hyperbolic arccotangent\n'; methods_str += '13 - versh(n) - hyperbolic versine\n'; methods_str += '14 - coversh(n) - hyperbolic coversine\n'; methods_str += '15 - haversh(n) - hyperbolic haversine\n\n'; methods_str += 'Graphics Extensions\n\n'; methods_str += '1 - distance(x1,y1,x2,y2) - distance between 2 points\n'; methods_str += '2 - angle(x1,y1,x2,y2) - angle of line in degrees\n'; methods_str += '3 - angle2Standard(angle) - Flash angle to standard geometric angle\n'; methods_str += '3a - lineAngle2Standard(angle) - Flash angle to standard geometric angle from points\n'; methods_str += '4 - averageAngle(arr) - average of an array of angles in degrees\n'; methods_str += '5 - polygonArea(arr) - area for convex and concave non-self-intersecting polygons\n'; methods_str += '6 - toPoint(vec) - convert vector head to Cartesian coordinates\n'; methods_str += '7 - toPolar(vec) - convert vector to polar coordinates\n'; methods_str += '8 - intersectLines(line1,line2) - intersection of two lines\n'; methods_str += '9 - deg2Dms(deg) - convert degrees to deg:min:sec\n'; methods_str += '10 - dms2Deg(dms_str="36:3:12") - convert deg:min:sec to degrees\n'; methods_str += '11 - convertDeg(deg,out_str="dms") - convert degrees to deg:min:sec\n'; methods_str += '11a - convertDeg(deg,out_str="rad") - convert degrees to radians\n'; methods_str += '11b - convertDeg(deg,out_str="multPI") - convert degrees to multiple of PI\n'; methods_str += '12 - convertRad(rad,out_str="dms") - convert radians to deg:min:sec\n'; methods_str += '12a - convertRad(rad,out_str="deg") - convert radians to degrees\n'; methods_str += '12b - convertRad(rad,out_str="multPI") - convert radians to multiple of PI\n'; methods_str += '13 - convertMultPI(multPI,out_str="dms") - convert multiple of PI to deg:min:sec\n'; methods_str += '13a - convertMultPI(multPI,out_str="deg") - convert multiple of PI to degrees\n'; methods_str += '13b - convertMultPI(multPI,out_str="rad") - convert multiple of PI to radians\n'; methods_str += '14 - convertDms(dms_str,out_str="multPI") - convert deg:min:sec to multiple of PI\n'; methods_str += '14a - convertDms(dms_str,out_str="deg") - convert deg:min:sec to degrees\n'; methods_str += '14b - convertDms(dms_str,out_str="rad") - convert deg:min:sec to radians\n\n'; methods_str += 'Miscellaneous Number Extensions\n\n'; methods_str += '1 - ln(n) - natural logarithm of parameter "n"\n'; methods_str += '2 - log_a(a,n) - logarithm base "a" of "n"\n'; methods_str += '3 - sign(n) - sign of a number\n'; methods_str += '4 - placesRound(a,b) - rounds "a" to "b" decimal places\n'; methods_str += '5 - randomBetween(a,b) - random number between "a" and "b"\n'; methods_str += '6 - summation(n,x) - sum of all numbers between 1 and "n" raised to "x" power\n'; methods_str += '7 - product(arr) - product of array elements\n'; methods_str += '8 - sum(arr) - sum of array elements\n'; methods_str += '9 - square(n) - number squared\n'; methods_str += '10 - inverse(n) - number inversed\n'; methods_str += '11 - fp(n) - decimal portion of floating point number\n'; methods_str += '12 - pow2(a,n) - solves the negative value input bug\n'; methods_str += '13 - nRoot(a,n) - nth root of a number\n'; methods_str += '14 - base(n,a) - convert decimal to base "a"\n'; methods_str += '14a - base(n,a,b) - convert base "a" to base "b"\n'; methods_str += '15 - maxSort(arr,bList) - sort max-min and return array\n'; methods_str += '15a - maxSort(arr) - sort max-min and return array[0] element\n'; methods_str += '16 - minSort(arr,bList) - sort min-max and return array\n'; methods_str += '16a - minSort(arr - sort min-max and return array[0] element\n'; methods_str += '17 - factorial(n) - factorial of a positive integer\n'; methods_str += '18 - Gamma_approx(n) - extends the domain of the factorial function by calculating the factorial of decimal numbers\n'; methods_str += '19 - factorial_approx(n) - uses the Gamma function to approximate factorial - very fast\n'; methods_str += '20 - permutations(n,r) - number of ways to arrange a list - order matters\n'; methods_str += '21 - combinations(n,r) - number of ways to arrange a list - order doesn\'t matter\n'; methods_str += '22 - productFactors(n) - product of all factors of "n" squared\n'; methods_str += '23 - fibonacci(n) - total fibonnacci levels of "n"\n'; methods_str += '24 - isPrime(n) - boolean for prime integer\n'; methods_str += '25 - findPrimeFrom(n) - array of all primes for positive integer between "from" and "n" inclusive\n'; methods_str += '26 - primeFactor(n) - string of an integer\'s prime factorization\n'; methods_str += '27 - totient(n)- total relative primes of "n"\n'; methods_str += '28 - isEven(n) - boolean for even integer\n'; methods_str += '29 - isOdd(n) - boolean for odd integer\n'; methods_str += '30 - gcd(a,b) - greatest common divisor\n'; methods_str += '31 - lcm(a,b) - lowest common multiple\n'; methods_str += '32 - percentage(a,b) - convert fraction to percentage\n'; methods_str += '33 - mean(arr) - mean of array\n'; methods_str += '34 - variance(arr) - variance of array\n'; methods_str += '35 - sd(arr) - standard deviation of array\n'; methods_str += '36 - round2(num) - rounds negative numbers down\n'; methods_str += '37 - formatDecimals(num,digits) - format number to specified decimals and 0 pad right\n'; methods_str += '38 - toScientific(num,sigDigs) - scientific notation to specified significant digits\n'; methods_str += '39 - fromScientific(num) - string representation of a decimal-based number from scientific notation ... accepts negative number and/or exponent input\n'; ///////////////////////////////////////////////////////////////////// // Math Extensions Wrapper ///////////////////////////////////////////////////////////////////// // check if the file has already been included if (!_global._MATHEXTENSIONS_AS) { // file has not been included // variable to let scripts that #include this file // know if it has already been included or not _global._MATHEXTENSIONS_AS = true; // Trace Alert development tool if (alert_ta) traceAlert(methods_str); ///////////////////////////////////////////////////////////////////// // Constants ///////////////////////////////////////////////////////////////////// // *** 1 & 2 have been proven to be slower than directly applying Math.PI within // the computation so I've included Robert Penner's trig-decimal functions ... // I'll leave DEG2RAD and RAD2DEG in place for now. // 1 - math constant: change degrees to radians ... Math.PI/180 Math.DEG2RAD = 0.0174532925199433; // 2 - math constant: change radians to degrees ... 180/Math.PI Math.RAD2DEG = 57.2957795130823; // 3 - math constant: the golden mean (phi) ... (1+Math.sqrt(5))/2 Math.PHI = 1.61803398874989; // 4 - math constant: Euler-Mascheroni constant (lamda or C) ... // ( n ) // lim ( sigma 1/k - ln(n) ) // n->oo ( k=1 ) Math.LAMBDA = 0.57721566490143; ////////////////////////////////////////////////////////////////////// // Trigonometry extensions ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////// // Trig-decimal functions ////////////////////////////////////////////////// // 1 - sinD Math.sinD = function(angle) { return Math.sin(angle*(Math.PI/180)); }; // 2 - cosD Math.cosD = function(angle) { return Math.cos(angle*(Math.PI/180)); }; // 3 - tanD Math.tanD = function(angle) { return Math.tan(angle*(Math.PI/180)); }; // 4 - asinD Math.asinD = function(ratio) { return Math.asin(ratio)*(180/Math.PI); }; // 5 - acosD Math.acosD = function(ratio) { return Math.acos(ratio)*(180/Math.PI); }; // 6 - atanD Math.atanD = function(ratio) { return Math.atan(ratio)*(180/Math.PI); }; // 7 - atan2D Math.atan2D = function(y,x) { return Math.atan2(y,x)*(180/Math.PI); }; ////////////////////////////////////////////////// // Circular trigonometric functions ////////////////////////////////////////////////// // 8 - secant Math.sec = function(angle) { return (1/Math.cos(angle)); }; // 9 - arcsecant Math.asec = function(ratio) { return (Math.acos(1/ratio)); }; // 10 - cosecant Math.csc = function(angle) { return (1/Math.sin(angle)); }; // 11 - arccosecant Math.acsc = function(ratio) { return (Math.asin(1/ratio)); }; // 12 - cotangent Math.cot = function(angle) { return (1/Math.tan(angle)); }; // 13 - arccotangent Math.acot = function(ratio) { return (Math.atan(1/ratio)); }; // 14 - versine Math.vers = function(n) { return 1-Math.cos(n); }; // 15 - coversine Math.covers = function(n) { return 1-Math.sin(n); }; // 16 - haversine Math.havers = function(n) { return 0.5*(1-Math.cos(n)); }; // 17 - cohaversine Math.cohavers = function(n) { return 0.5*(1-Math.sin(n)); }; // 18 - exsecant Math.exsec = function(n) { return 1/Math.cos(n)-1; }; // 19 - coexsecant Math.coexsec = function(n) { return 1/Math.sin(n)-1; }; // 20 - arcversine Math.avers = function(n) { return Math.atan(Math.sqrt(2*n-n*n)/(1-n)); }; // 21 - arccoversine Math.acovers = function(n) { return Math.atan((1-n)/Math.sqrt(2*n-n*n)); }; // 22 - archaversine Math.ahavers = function(n) { return Math.atan(2*Math.sqrt(n-n*n)/(1-2*n)); }; // 23 - arcexsecant Math.aexsec = function(n) { return Math.atan(Math.sqrt(n*n+2*n)); }; ////////////////////////////////////////////////// // Hyperbolic trigonometric functions ////////////////////////////////////////////////// // 1 - hyperbolic sine = (Eª-E-ª)/2 Math.sinh = function(n) { return (Math.exp(n)-Math.exp(-n))/2; }; // 2 - hyperbolic arcsine = ln(n+sqrt(n²+1) Math.asinh = function(n) { return Math.log(n+Math.sqrt(n*n+1)); }; // 3 - hyperbolic cosine = (Eª+E-ª)/2 Math.cosh = function(n) { return (Math.exp(n)+Math.exp(-n))/2; }; // 4 - hyperbolic arccosine = ln(n+sqrt(n²-1) Math.acosh = function(n) { return Math.log(n+Math.sqrt(n*n-1)); }; // 5 - hyperbolic tangent = sinh(n)/cosh(n) = (Eª-E-ª)/(Eª+E-ª) Math.tanh = function(n) { var t1 = Math.exp(n); var t2 = Math.exp(-n); return (t1-t2)/(t1+t2); }; // 6 - hyperbolic arctangent = ln((1+n)/(1-n))/2 Math.atanh = function(n) { return Math.log((1+n)/(1-n))/2; }; // 7 - hyperbolic secant = 1/cosh(n) = 1/(Eª+E-ª)/2 Math.sech = function(n) { return (1/Math.cosh(n)); }; // 8 - hyperbolic arcsecant = acosh(1/n) = ln((1/n)+sqrt((1/n)²-1) Math.asech = function(n) { return (Math.acosh(1/n)); }; // 9 - hyperbolic cosecant = 1/sinh(n) = 1/((Eª-E-ª)/2) Math.csch = function(n) { return (1/Math.sinh(n)); }; // 10 - hyperbolic arccosecant = asinh(1/n) = ln((1/n)+sqrt((1/n)²+1) Math.acsch = function(n) { return (Math.asinh(1/n)); }; // 11 - hyperbolic cotangent = 1/tanh(n) = 1/(sinh(n)/cosh(n)) = 1/((Eª-E-ª)/(Eª+E-ª)) Math.coth = function(n) { return (1/Math.tanh(n)); }; // 12 - hyperbolic arccotangent = atanh(1/n) = ln((1+(1/n))/(1-(1/n)))/2 Math.acoth = function(n) { return (Math.atanh(1/n)); }; // 13 - hyperbolic versine = 1-0.5*(exp(n)+exp(-n)) Math.versh = function(n) { return 1-0.5*(Math.exp(n)+Math.exp(-n)); }; // 14 - hyperbolic coversine = 1-0.5*(exp(n)-exp(-n)) Math.coversh = function(n) { return 1-0.5*(Math.exp(n)-Math.exp(-n)); }; // 15 - hyperbolic haversine 0.5*(1-0.5*(exp(n)+exp(-n))) Math.haversh = function(n) { return 0.5*(1-0.5*(Math.exp(n)+Math.exp(-n))); }; ///////////////////////////////////////////////////////////////////// // Graphics extensions ///////////////////////////////////////////////////////////////////// // 1 - returns total distance between 2 points Math.distance = function(x1,y1,x2,y2) { var dX = x2-x1; var dY = y2-y1; return Math.sqrt(dX*dX+dY*dY); }; // 2 - returns angle of line in degrees Math.angle = function(x1,y1,x2,y2) { return Math.atan2(y2-y1,x2-x1)*180/Math.PI; }; // 3 - changes a Flash angle into standard position - angle in degrees Math.angle2Standard = function(angle) { var ang = 360-(((angle%=360)<0) ? angle+360 : angle); return (ang==360) ? 0 : ang; }; // 3a - returns angle of line changed from Flash into standard position - angle in degrees Math.lineAngle2Standard = function(x1,y1,x2,y2) { var angle = Math.atan2(y2-y1,x2-x1)*180/Math.PI; var ang = 360-(((angle%=360)<0) ? angle+360 : angle); return (ang==360) ? 0 : ang; }; // 4a - dependent sort by number function function numSort(a,b) { return (a-b); } // 4 - argument: an array of angles in degrees Math.averageAngle = function(arr) { // sort array to prepare for hemisphere check arr.sort(numSort); // hemisphere check and summation var len = arr.length; var temp = arr[0]; for (var j=1;jarr[0]+180) { arr[j] = -(360-arr[j]); } temp += arr[j]; } // average of summation temp /= len; // change final average angle to a positive reading if (temp<0) temp += 360; return temp; }; // 5 - return the area of a convex or concave, non-self-intersecting polygon Math.polygonArea = function(arr) { var op1,op2; var len = arr.length; for (var j=0;j0) { // there is a deg and min deg = parseInt(dms_str.substring(0,dpos)); if (spos>0) { // there is a sec mn = parseInt(dms_str.substring(dpos+1,spos)); sc = parseFloat(dms_str.substring(spos+1,dms_str.length)); } else { // no sec mn = parseInt(dms_str.substring(dpos+1,dms_str.length)); sc = 0; } } else { // only deg deg = parseInt(dms_str); mn = 0; sc = 0; } return deg+(mn+(sc/60))/60; //decimal degrees }; // 10 - decimal degrees to deg:min:sec string Math.deg2Dms = function(deg) { var adg = Math.abs(deg); var fdg = Math.floor(adg); var fsc = adg*3600%60; var fmn = Math.floor(adg*60%60); if (deg<0) fdg = -fdg; return fdg.toString()+":"+fmn.toString()+":"+fsc.toString(); }; // 11 - deg in :: out_str = 'dms','rad','multPI' Math.convertDeg = function(deg,out_str) { if (out_str=='dms') return Math.deg2Dms(x); else if (out_str=='rad') return deg*Math.PI/180; else if (out_str=='multPI') return deg/180; }; // 12 - rad in :: out_str = 'dms','deg','multPI' Math.convertRad = function(rad,out_str) { if (out_str=='dms') return Math.deg2Dms(rad*180/Math.PI); else if (out_str=='deg') return rad*180/Math.PI; else if (out_str=='multPI') return rad/Math.PI; }; // 13 - multPI in :: out_str = 'dms','deg','rad' Math.convertMultPI = function(multPI,out_str) { if (out_str=='dms') return Math.deg2Dms(multPI*180); else if (out_str=='deg') return multPI*180; else if (out_str=='rad') return multPI*Math.PI; }; // 14 - dms_str='deg:min:sec' in :: out_str = 'multPI','deg','rad' Math.convertDms = function(dms_str,out_str) { var x = Math.dms2Deg(dms_str); if (out_str=='multPI') return x/180; else if (out_str=='deg') return x; else if (out_str=='rad') return x*Math.PI/180; }; ///////////////////////////////////////////////////////////////////// // Miscellaneous number extensions ///////////////////////////////////////////////////////////////////// // 1 - returns the natural logarithm of "n" Math.ln = function(n) { return (Math.log(n)); }; // 2 - returns the logarithm with base "a" of "n" Math.log_a = function(a,n) { return (Math.log(n)/Math.log(a)); }; // 3 - returns the sign of the number Math.sign = function(n) { return n==0 ? 0 : (n>0 ? 1 : -1); }; // 4 - rounds "a" to "b" number of decimal places Math.placesRound = function(a,b) { return (Math.round(a*Math.pow(10,b))/Math.pow(10,b)); }; // 5 - returns a random number between "a" and "b" Math.randomBetween = function(a,b) { var greater = Math.max(a,b); var smaller = Math.min(a,b); return (Math.random()*(greater-smaller)+smaller); }; // 6 - returns the sum of all the numbers between one // and "n" raised to the "x" power. Math.summation = function(n,x) { var sum = 0; for (var j=1;j<=n;j++) { sum += Math.pow(j,x); } return (sum); }; // 7 - returns product of "arr" elements Math.product = function(arr) { var k = 1; for (var h=0;h0 ? Math.pow(a,n) : Math.pow(a*-1,n)*-1); }; // 13 - returns the nth root of a number Math.nRoot = function(a,n) { return this.pow2(a,1/n); }; // 14 - converts "n", 2 arg: from base 10 to base"a", 3 arg: from base "a" to base "b" Math.base = function(n,a,b) { if (b==null) { b = a; a = 10; } if (typeof(n)=="number") { j = new Array(Math.floor(Math.log_a(10,n))+1); for (var h=j.length;h>0;h--) { j[j.length-h] = Math.floor(n/Math.pow(10,h-1)); n %= Math.pow(10,h-1); } n = j; } k = 0; for (var h=n.length;h>0;h--) k += n[n.length-h]*Math.pow(a,h-1); n = k; j = new Array(Math.floor(Math.log_a(b,n))+1); for(var h=j.length;h>0;h--) { j[j.length-h] = Math.floor(n/Math.pow(b,h-1)); n %= Math.pow(b,h-1); } n = j; k = 1; for (var h=0;h0;h--) k += n[n.length-h]*Math.pow(10,h-1); n = k; } return n; }; // 15 - returns max of "arr", or max2min order of "arr" Math.maxSort = function(arr,bList) { var b,c; if (bList) return arr.sort(function(b,c) {return c-b}); else return arr.sort(function(b,c) {return c-b})[0]; }; // 16 - returns min of "arr", or min2max order of "arr" Math.minSort = function(arr,bList) { var b,c; if (bList) return arr.sort(function(b,c) {return b-c}); else return arr.sort(function(b,c) {return b-c})[0]; }; // 17 - returns factorial of a positive integer Math.factorial = function(n) { if (n!=0) { return n*Math.factorial(n-1); } else { return (1); } }; // 18 - extends the domain of the factorial function by calculating the factorial of decimal numbers Math.Gamma_approx = function(n) { var x = n-1; return (Math.sqrt ((2*x+1/3)*Math.PI) * Math.pow(x,x)*Math.exp(-x)); }; // 19 - uses the Gamma function to approximate factorial - very fast Math.factorial_approx = function (n) { return (Math.round(Math.Gamma_approx(n+1))); }; // 20 - number of ways to arrange a list - order matters Math.permutations = function(n,r) { return Math.factorial(n)/Math.factorial(n-r); }; // 21 - number of ways to arrange a list - order doesn't matter Math.combinations = function(n,r) { return Math.permutations(n,r)/Math.factorial(r); }; // 22 - returns product of factors of "n" Math.productFactors = function(n) { var k = 1; for (var h=3;h<=n;h+=2) if (Math.isPrime(h)) k *= h; if (n>2) k *= 2; return k; }; // 23 - returns total fibonacci levels in "n" Math.fibonacci = function(n) { return Math.round((Math.pow((1+Math.sqrt(5))/2,n)-Math.pow((1-Math.sqrt(5))/2,n))/Math.sqrt(5)); }; // 24 - returns boolean for "isPrime" integer condition, ignores decimals Math.isPrime = function(n) { n |= 0; if (isNaN(n) || n==0) return 0; if (n<=3) return 1; if (n%2==0) return 0; var iMax = Math.floor(Math.sqrt(n)); for (var h=3; h<=iMax;h+=2) if (n%h==0) return 0; return 1; }; // 24a - returns boolean for "isPrime" integer condition, ignores decimals // I can't get this to work with new prime functions below, so I'm using // the slower version above for now ... it works on it's own, however!! Math.isPrime2 = function(n) { n |= 0; if (isNaN(n) || n==0) return false; if (n<=3) return true; if (n%2==0) return false; var iMax = (Math.sqrt(n)/6 | 0)*6+5; var j = 5; while (n%j!=0 && n%(j+2)!=0 && (j+=6)!=iMax) { } return (j==iMax); }; // diu - June 2003 // 25 - returns an array of all primes between "from" and "n" inclusive, // positive but restricted integer value, ignores decimals Math.findPrimeFrom = function(n,from) { n |= 0; from |= 0; var i, j; var output_array = []; var count_array = []; if (!from) from = 0; else from -= 1; n += 1; for (i=0;ifrom;i--) { if (count_array[i] == 0) { output_array.push(i); } } return output_array; }; // persist - June 2003 // 26 - returns prime factors of "n", positive but // restricted integer value, ignores decimals Math.primeFactor = function(n) { n |= 0; if (n==1) return 1; var temp = n; var delim = '*'; var factor_str = ""; while (1) { if (temp%2==0) { temp /= 2; factor_str += 2+delim; } else break; } var num = 3; while (1 -6) // Math.round() actually rounds neg. #s up (-5.5 -> -5) Math.round2 = function(num) { if (num<0) { var isNegative = true; num *= -1; } return isNegative ? -Math.round(num) : Math.round(num); }; // Robert Penner - May 2001 // 37 - format a number into specified number of decimal places and 0 pad right Math.formatDecimals = function(num,digits) { //if no decimal places needed, we're done if (digits<=0) { return Math.round(num); } //round the number to specified decimal places //e.g. 12.3456 to 3 digits (12.346) -> mult. by 1000, round, div. by 1000 var tenToPower = Math.pow(10,digits); var cropped = String(Math.round(num*tenToPower)/tenToPower); //add decimal point if missing if (cropped.indexOf(".")==-1) { cropped += ".0"; //e.g. 5 -> 5.0 (at least one zero is needed) } //finally, force correct number of zeroes; add some if necessary var halves = cropped.split("."); //grab numbers to the right of the decimal //compare digits in right half of string to digits wanted var zerosNeeded = digits-halves[1].length; //number of zeros to add for (var i=1;i<=zerosNeeded;i++) { cropped += "0"; } return(cropped); }; // Robert Penner - May 2001 // 38 - convert any number to a string representation of scientific notation with specified significant digits // e.g. .012345 -> 1.2345e-2 -- but 6.34e0 is displayed "6.34" // requires function formatDecimals() Math.toScientific = function(num,sigDigs) { //deal with messy input values num = Number(num); //try to convert to a number if (isNaN(num)) return num; //garbage in, NaN out //find exponent using logarithm //e.g. log10(150) = 2.18 -- round down to 2 using floor() var exponent = Math.floor(Math.log(Math.abs(num))/Math.LN10); if (num==0) exponent = 0; //handle glitch if the number is zero //find mantissa (e.g. "3.47" is mantissa of 3470; need to divide by 1000) var tenToPower = Math.pow(10,exponent); var mantissa = num/tenToPower; //force significant digits in mantissa //e.g. 3 sig digs: 5 -> 5.00, 7.1 -> 7.10, 4.2791 -> 4.28 mantissa = Math.formatDecimals(mantissa,sigDigs-1); //use custom function // it is possible that by rounding in the step above, we've increased // the number to XX.XXX, e.g. 9.999999 went to 10.00 // so we need to check for this condition if (mantissa>=10 || mantissa<=-10) { mantissa /= 10; mantissa = Math.formatDecimals(mantissa,sigDigs-1); exponent++; } var output = mantissa; //if exponent is zero, don't include e if (exponent!=0) { output += "e"+exponent; } return (output); }; // Robert Penner - May 2001 // 39 - returns string representation of a decimal-based number from // scientific notation ... accepts negative number and/or exponent input Math.fromScientific = function(n) { var bNeg, bNegE, negE, padInc, pad; var temp = n.toString(); if (temp.indexOf('-')==0) bNeg = 1, temp = temp.substr(1); if (temp.lastIndexOf('-')>-1) { negE = temp.lastIndexOf('-'); bNegE = 1; padInc = temp.substr(negE+1); temp = temp.substr(0,negE)+padInc; padInc = Number(padInc)-1; } var a, r, t = temp; if(t.indexOf("e")>-1) { var e = Number((r=t.split("e"))[1]); r[0] = r[0].substr(0,a = r[0].indexOf("."))+r[0].slice(a+1); r[1] = Number(r[1])-(r[0].length-a); if (!bNegE) { while (r[1]--) r[0] += "0"; var x = r[0].length; while((x-=3)>0) r[0] = r[0].substr(0,x)+","+r[0].substr(x); if (bNeg) r[0] = "-"+r[0]; return r[0]; } else { while (padInc--) pad += "0"; r[0] = "."+pad+r[0]; if (bNeg) r[0] = "-"+r[0]; return r[0]; } } return t; }; // adapted from Gary Fixler - 2003 ///////////////////////////////////////////////////////////////////// // Test MathExtensions.as ///////////////////////////////////////////////////////////////////// /* // Constants trace("*************************** Constants\n"); trace("1 - DEG2RAD: "+Math.DEG2RAD); trace("2 - RAD2DEG: "+Math.RAD2DEG); trace("3 - PHI: "+Math.PHI); trace("4 - LAMBDA: "+Math.LAMBDA+newline); // Trigonometric Functions trace("\n*************************** Trigonometric Functions\n"); trace("1 - sinD(angle:85): "+Math.sinD(85)); trace("2 - cosD(angle:85): "+Math.cosD(85)); trace("3 - tanD(angle:85): "+Math.tanD(85)); trace("4 - asinD(ratio:2/3): "+Math.asinD(2/3)); trace("5 - acosD(ratio:2/3): "+Math.acosD(2/3)); trace("6 - atanD(ratio:2/3): "+Math.atanD(2/3)); trace("7 - atan2D(y:85,x:45): "+Math.atan2D(85,45)); trace("8 - sec(angle:85*Math.PI/180): "+Math.sec(85*Math.PI/180)); trace("9 - asec(ratio:4/2): "+Math.asec(4/2)); trace("10 - csc(angle:85*Math.PI/180): "+Math.csc(85*Math.PI/180)); trace("11 - acsc(ratio:4/3): "+Math.acsc(4/3)); trace("12 - cot(angle:85*Math.PI/180): "+Math.cot(85*Math.PI/180)); trace("13 - acot(ratio:1/4): "+Math.acot(1/4)); trace("14 - vers(n:85*Math.PI/180): "+Math.vers(85*Math.PI/180)); trace("15 - covers(n:85*Math.PI/180): "+Math.covers(85*Math.PI/180)); trace("16 - havers(n:85*Math.PI/180): "+Math.havers(85*Math.PI/180)); trace("17 - cohavers(n:85*Math.PI/180): "+Math.cohavers(85*Math.PI/180)); trace("18 - exsec(n:85*Math.PI/180): "+Math.exsec(85*Math.PI/180)); trace("19 - coexsec(n:85*Math.PI/180): "+Math.coexsec(85*Math.PI/180)); trace("20 - avers(ratio:.36): "+Math.avers(.36)); trace("21 - acovers(n:85*Math.PI/180): "+Math.acovers(85*Math.PI/180)); trace("22 - ahavers(ratio:.36): "+Math.ahavers(.36)); trace("23 - aexsec(n:85*Math.PI/180): "+Math.aexsec(85*Math.PI/180)); // Hyperbolic Trigonometric Functions trace("\n*************************** Hyperbolic Trigonometric Functions\n"); trace("1 - sinh(n:85*Math.PI/180): "+Math.sinh(85*Math.PI/180)); trace("2 - asinh(n:85*Math.PI/180): "+Math.asinh(85*Math.PI/180)); trace("3 - cosh(n:85*Math.PI/180): "+Math.cosh(85*Math.PI/180)); trace("4 - acosh(n:85*Math.PI/180): "+Math.acosh(85*Math.PI/180)); trace("5 - tanh(n:85*Math.PI/180): "+Math.tanh(85*Math.PI/180)); trace("6 - atanh(n:85*Math.PI/180): "+Math.atanh(5*Math.PI/180)); trace("7 - sech(n:85*Math.PI/180): "+Math.sech(85*Math.PI/180)); trace("8 - asech(n:85*Math.PI/180): "+Math.asech(5*Math.PI/180)); trace("9 - csch(n:85*Math.PI/180): "+Math.csch(85*Math.PI/180)); trace("10 - acsch(n:85*Math.PI/180): "+Math.acsch(85*Math.PI/180)); trace("11 - coth(n:85*Math.PI/180): "+Math.coth(85*Math.PI/180)); trace("12 - acoth(n:85*Math.PI/180): "+Math.acoth(85*Math.PI/180)); trace("13 - versh(n:85*Math.PI/180): "+Math.versh(85*Math.PI/180)); trace("14 - coversh(n:85*Math.PI/180): "+Math.coversh(85*Math.PI/180)); trace("15 - haversh(n:85*Math.PI/180): "+Math.haversh(85*Math.PI/180)); // Graphics Functions trace("\n*************************** Graphics Functions\n"); trace("1 - distance(x1:100,y1:100,x2:300,y2:300): "+Math.distance(100,100,300,300)); trace("2 - angle(x1:100,y1:100,x2:300,y2:300): "+Math.angle(100,100,300,300)); trace("3 - angle2Standard(angle:-187): "+Math.angle2Standard(-187)); trace("3a - lineAngle2Standard(angle:x1:100,y1:100,x2:300,y2:300): "+Math.lineAngle2Standard(100,100,300,300)); trace("4 - averageAngle(data_array:[330,30,270]): "+Math.averageAngle([330,30,270])); poly_arr = [{x:20,y:50},{x:100,y:100},{x:200,y:40},{x:220,y:230},{x:120,y:190},{x:30,y:270}]; trace("5 - polygonArea(arr:poly_arr(see code),len:6): "+Math.polygonArea(poly_arr)); vec1 = Math.toPoint({a:25,r:100}); trace("6 - toPoint(vec:{a:25,r:100}): x: "+vec1.x+", y:"+vec1.y); vec2 = Math.toPolar({x:100,y:100}); trace("7 - toPolar(vec:{x:100,y:100}): a: "+vec2.a+", r:"+vec2.r); line1_obj = {p1x:112,p1y:104,p2x:512,p2y:513}; line2_obj = {p1x:11,p1y:452,p2x:330,p2y:52}; intPt = Math.intersectLines(line1_obj,line2_obj); trace("8 - intersectLines(line1:(see code),line2:(see code)): x:"+intPt.x+", y:"+intPt.y); // angle conversion functions dms_str = '36:3:12'; trace("9 - deg2Dms(deg): "+Math.deg2Dms(85)); trace("10 - dms2Deg(dms_str='36:3:12'): "+Math.dms2Deg(dms_str)); trace("11 - convertDeg(deg,out_str='dms'): "+Math.convertDeg(85,'dms')); trace("11a - convertDeg(deg,out_str='rad'): "+Math.convertDeg(85,'rad')); trace("11b - convertDeg(deg,out_str='multPI'): "+Math.convertDeg(85,'multPI')); trace("12 - convertRad(rad,out_str='dms'): "+Math.convertRad(2.1,'dms')); trace("12a - convertRad(rad,out_str='deg'): "+Math.convertRad(2.1,'deg')); trace("12b - convertRad(rad,out_str='multPI'): "+Math.convertRad(2.1,'multPI')); trace("13 - convertMultPI(multPI,out_str='dms'): "+Math.convertMultPI(85/180,'dms')); trace("13a - convertMultPI(multPI,out_str='deg'): "+Math.convertMultPI(85/180,'deg')); trace("13b - convertMultPI(multPI,out_str='rad'): "+Math.convertMultPI(85/180,'rad')); trace("14 - convertDms(dms_str,out_str='multPI'): "+Math.convertDms(dms_str,'multPI')); trace("14a - convertDms(dms_str,out_str='deg'): "+Math.convertDms(dms_str,'deg')); trace("14b - convertDms(dms_str,out_str='rad'): "+Math.convertDms(dms_str,'rad')); // Miscellaneous Number Functions arr = [10,303,244,521,105,22,643,12]; trace("\n*************************** Miscellaneous Number Functions\n"); trace("arr = [10,303,244,521,105,22,643,12]"); trace("1 - ln(n:14): "+Math.ln(14)); trace("2 - log_a(a:3,n:14): "+Math.log_a(3,14)); trace("3 - sign(n:-1445): "+Math.sign(-1445)); trace("4 - placesRound(a:1.34564,b:3): "+Math.placesRound(1.34564,3)); trace("5 - randomBetween(a:2,b:200): "+Math.randomBetween(2,200)); trace("6 - summation(n:45,x:4): "+Math.summation(45,4)); trace("7 - product(arr): "+Math.product(arr)); trace("8 - sum(arr): "+Math.sum(arr)); trace("9 - square(n:12): "+Math.square(12)); trace("10 - inverse(n:12): "+Math.inverse(12)); trace("11 - fp(n:134.23456): "+Math.fp(134.23456)); trace("12 - pow2(a:-23,n:2): "+Math.pow2(-23,2)); trace("13 - nRoot(a:36,n:3): "+Math.nRoot(36,3)); trace("14 - base(n:85,a:2): "+Math.base(85,2)); trace("14a - base(n:85,a:10,b:2): "+Math.base(85,10,2)); trace("15 - maxSort(arr,bList:1): "+Math.maxSort(arr,1)); trace("15a - maxSort(arr): "+Math.maxSort(arr)); trace("16 - minSort(arr,bList:1): "+Math.minSort(arr,1)); trace("16a - minSort(arr): "+Math.minSort(arr)); trace("17 - factorial(n:25): "+Math.factorial(25)); trace("18 - Gamma_approx(n:25.123): "+Math.Gamma_approx(25.123)); trace("19 - factorial_approx(n:25.123): "+Math.factorial_approx(25.123)); trace("20 - permutations(n:20,r:5): "+Math.permutations(20,5)); trace("21 - combinations(n:20,r:5): "+Math.combinations(20,5)); trace("22 - productFactors(n:742.999999999999943159): "+Math.productFactors(742.999999999999943159)); trace("23 - fibonacci(n:10): "+Math.fibonacci(10)); trace("24 - isPrime(n:223): "+Math.isPrime(223)); trace("25 - findPrimeFrom(n:3000,[from]:2000): "+Math.findPrimeFrom(3000,2000)); trace("26 - primeFactor(n:100234568): "+Math.primeFactor(100234568)); trace("27 - totient(n:85): "+Math.totient(85)); trace("28 - isEven(n:224): "+Math.isEven(224)); trace("29 - isOdd(n:223): "+Math.isOdd(223)); trace("30 - gcd(a:5,b:2555): "+Math.gcd(5,2555)); trace("31 - lcm(a:5,b:2555): "+Math.lcm(5,2555)); trace("32 - percentage(a:23,b:45): "+Math.percentage(23,45)); trace("33 - mean(arr): "+Math.mean(arr)); trace("34 - variance(arr): "+Math.variance(arr)); trace("35 - sd(arr): "+Math.sd(arr)); trace("36 - round2(num:-5.5267))): "+Math.round2(-5.5267)); trace("37 - formatDecimals(num:5,digits:4): "+Math.formatDecimals(5,4)); trace("38 - toScientific(num:1002003004,sigDigs:5): "+Math.toScientific(1002003004,5)); trace("39 = fromScientific(num:-1.6543456e-34): "+Math.fromScientific(-1.6543456e-34)); trace("39a = fromScientific(num:-1.6543456e34): "+Math.fromScientific(-1.6543456e34)); */ } // closes the 'if' statement that checked if this file had already been included