Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2013
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Math.cos = function(a)
  2. {
  3.     // Bring a into the 0 to +pi range without expensive branching.
  4.     // Uses the symmetry that cos is even.
  5.     a = (a + Math.PI) % (2*Math.PI);
  6.     a = Math.abs((2*Math.PI + a) % (2*Math.PI) - Math.PI);
  7.    
  8.     // make b = 0 if a < pi/2 and b=1 if a > pi/2
  9.     var b = (a-Math.PI/2) + Math.abs(a-Math.PI/2);
  10.     b = b/(b+1e-30); // normalize b to one while avoiding divide by zero errors.
  11.    
  12.     // if a > pi/2 send a to pi-a, otherwise just send a to -a which has no effect
  13.     // Using the symmetry cos(x) = -cos(pi-x) to bring a to the 0 to pi/2 range.
  14.     a = b*Math.PI - a;
  15.    
  16.     var c = 1 - 2*b; // sign of the output
  17.    
  18.     // Taylor expansion about 0 with a correction term in the quadratic to make cos(pi/2)=0
  19.     return c * (1 - a*a*(0.5000000025619951 - a*a*(1/24 - a*a*(1/720 - a*a*(1/40320 - a*a*(1/3628800 - a*a/479001600))))));
  20. };
  21.  
  22. Math.sin = function(a)
  23. {
  24.     return Math.cos(a - Math.PI/2);
  25. };
  26.  
  27. // Returns angle from -pi/2 to pi/2
  28. Math.atan = function(a)
  29. {
  30.     var tanPiBy6 = 0.5773502691896257;
  31.     var tanPiBy12 = 0.2679491924311227;
  32.     var sign = 1;
  33.     var inverted = false;
  34.     var tanPiBy6Shift = 0;
  35.    
  36.     if (a < 0){
  37.         // tan(x) = -tan(-x) so remove sign now and put it back at the end
  38.         sign = -1;
  39.         a *= -1;
  40.     }
  41.    
  42.     if (a > 1)
  43.     {
  44.         // tan(pi/2 - x) = 1/tan(x)
  45.         inverted = true;
  46.         a = 1/a;
  47.     }
  48.    
  49.     if (a > tanPiBy12)
  50.     {
  51.         // tan(x-pi/6) = (tan(x) - tan(pi/6)) / (1 + tan(pi/6)tan(x))
  52.         tanPiBy6Shift = Math.PI/6;
  53.         a = (a - tanPiBy6) / (1 + tanPiBy6*a);
  54.     }
  55.     // Now a will be in the range [-tan(pi/12), tan(pi/12)]  
  56.    
  57.     // Use the taylor expansion around 0 with a correction to the linear term to match the pi/12 boundary
  58.     // atan(x) = x - x^3/3 + x^5/5 - ...
  59.     var r = a*(1.0000000000390272 - a*a*(1/3 - a*a*(1/5 - a*a*(1/7 - a*a*(1/9 - a*a*(1/11 - a*a*(1/13 - a*a/15)))))));
  60.    
  61.     // shift the result back where necessary
  62.     r += tanPiBy6Shift;
  63.     if (inverted)
  64.         r = Math.PI/2 - r;
  65.     return sign * r;
  66. };
  67.  
  68. Math.atan2 = function(y,x)
  69. {
  70.     // get unsigned x,y for ease of calculation, this means all angles are in the range [0, pi/2]
  71.     var ux = Math.abs(x);
  72.     var uy = Math.abs(y);
  73.     // holds the result in the upper right quadrant
  74.     var r;
  75.    
  76.     // Handle all edges cases to match the spec
  77.     if (uy === 0)
  78.     {
  79.         r = 0;
  80.     }
  81.     else
  82.     {
  83.         if (ux === 0)
  84.         {
  85.             r = Math.PI / 2;
  86.         }
  87.         if (uy === Infinity)
  88.         {
  89.             if (ux === Infinity)
  90.                 r = Math.PI / 4;
  91.             else
  92.                 r = Math.PI / 2;
  93.         }
  94.         else
  95.         {
  96.             if (ux === Infinity)
  97.                 r = 0;
  98.             else
  99.                 r = Math.atan(uy/ux);
  100.         }
  101.     }
  102.    
  103.     // puts the result into the correct quadrant
  104.     // 1/(-0) is the only way to determine the sign for a 0 value
  105.     if (x < 0 || 1/x === -Infinity)
  106.     {
  107.         if (y < 0 || 1/y === -Infinity)
  108.             return -Math.PI + r;
  109.         else
  110.             return Math.PI - r;
  111.     }
  112.     else
  113.     {
  114.         if (y < 0 || 1/y === -Infinity)
  115.             return -r;
  116.         else
  117.             return r;
  118.     }
  119. };
  120.  
  121. Math.acos = function()
  122. {
  123.     error("Math.acos() does not have a synchronization safe implementation");
  124. };
  125.  
  126. Math.asin = function()
  127. {
  128.     error("Math.asin() does not have a synchronization safe implementation");
  129. };
  130.  
  131. Math.tan = function()
  132. {
  133.     error("Math.tan() does not have a synchronization safe implementation");
  134. };
  135.  
  136. Math.pow = function(base, e)
  137. {
  138.     if (Math.round(e) == e)
  139.     {
  140.         if (e >= 0)
  141.         {
  142.             var a = Math.intPow(base, e);
  143.         }
  144.         else
  145.         {
  146.             var a = 1 / Math.intPow(base, -e);
  147.         }
  148.     }
  149.     else
  150.     {
  151.         var a = Math.exp(e*Math.ln(base));
  152.     }
  153.     warn(base+" ^ "+e+" = "+a);
  154.     return a;
  155. }
  156.  
  157. Math.exp = function(x)
  158. {
  159.     if (x < 0)
  160.     {
  161.         var iPart = 1/Math.intPow(Math.E, -Math.floor(x));
  162.     }
  163.     else
  164.     {
  165.         var iPart = Math.intPow(Math.E, Math.floor(x));
  166.     }
  167.  
  168.     x = x - Math.floor(x);
  169.     // x \in [0,1)
  170.  
  171.     if (x == 0)
  172.         // no need to loop if we know the answer
  173.         return iPart;
  174.  
  175.     // taylor series around 0
  176.     var fPart =1+x*(1+x*(1+x*(1+x*(1+x*(1+x*(1+x*(1+x*(1+x*(1+x/10)/9)/8)/7)/6)/5)/4)/3)/2);
  177.    
  178.     return iPart*fPart;
  179. }
  180.  
  181. Math.ln = function(x)
  182. {
  183.     // the binary logarithm of e
  184.     var lb_e = 1.442695040888963407359924681001892137426645954152985934135449;
  185.     return Math.lb(x) / lb_e;
  186. }
  187.  
  188. /**
  189.  * binary log implementation
  190.  *
  191.  * based on http://en.wikipedia.org/wiki/Binary_logarithm#Real_number
  192.  */
  193. Math.lb = function(x)
  194. {
  195.     if (x <= 0)
  196.     {
  197.         return -Infinity;
  198.     }
  199.  
  200.     // calculate to 20 fractional bits
  201.     var precisionBits = 20;
  202.  
  203.     // calculate integer log, rounded down
  204.     // when implemented in C, just count the number of bits before the fraction
  205.     // without leading zeros. This may be negative.
  206.     var log = 0;
  207.     if (x >= 1)
  208.     {
  209.         for (var i = 1; i <= x; i *= 2)
  210.         {
  211.             log++;
  212.         }
  213.         log--;
  214.         i /= 2;
  215.     }
  216.     else
  217.     {
  218.         for (var i = 1; i > x; i /= 2)
  219.         {
  220.             log--;
  221.         }
  222.     }
  223.     // now lb(x) = log + lb(y) with y = x/i. So y \in [1,2)
  224.  
  225.     var y = x/i;
  226.  
  227.     if (y <= 1)
  228.         // we're done, or there's a minimal rounding error, and we should be done
  229.         return log;
  230.  
  231.     var m = 0;
  232.     var add = 1;
  233.     while (true)
  234.     {
  235.         while (m <= precisionBits && y < 4)
  236.         {
  237.             m++;
  238.             y *= y;
  239.             add /= 2;
  240.         }
  241.         if (m > precisionBits)
  242.             break;
  243.         log += add;
  244.         y /= 2;
  245.     }
  246.    
  247.     return log;
  248.    
  249. }
  250. /**
  251.  * calculate the power for positive integer exponents
  252.  */
  253. Math.intPow = function(base, exp)
  254. {
  255.     var powers = [base];
  256.     var binary = [1];
  257.     var i = 0;
  258.     for (var e = 2; e <= exp; e *= 2)
  259.     {
  260.         // calculate base^i, using base^(i/2)
  261.         powers.push(powers[i]*powers[i]);
  262.         binary.push(e);
  263.         i++;
  264.     }
  265.  
  266.     var result = 1;
  267.  
  268.     var i = binary.length;
  269.  
  270.     while (exp > 0)
  271.     {
  272.         if (binary[--i] <= exp)
  273.         {
  274.             result *= powers[i];
  275.             exp -= binary[i];
  276.         }
  277.     }
  278.  
  279.     return result;
  280.  
  281. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement