Math-392d0035.js 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257
  1. /* This file is automatically rebuilt by the Cesium build process. */
  2. define(['exports', './when-e6985d2a', './Check-24cae389'], function (exports, when, Check) { 'use strict';
  3. /*
  4. I've wrapped Makoto Matsumoto and Takuji Nishimura's code in a namespace
  5. so it's better encapsulated. Now you can have multiple random number generators
  6. and they won't stomp all over eachother's state.
  7. If you want to use this as a substitute for Math.random(), use the random()
  8. method like so:
  9. var m = new MersenneTwister();
  10. var randomNumber = m.random();
  11. You can also call the other genrand_{foo}() methods on the instance.
  12. If you want to use a specific seed in order to get a repeatable random
  13. sequence, pass an integer into the constructor:
  14. var m = new MersenneTwister(123);
  15. and that will always produce the same random sequence.
  16. Sean McCullough (banksean@gmail.com)
  17. */
  18. /*
  19. A C-program for MT19937, with initialization improved 2002/1/26.
  20. Coded by Takuji Nishimura and Makoto Matsumoto.
  21. Before using, initialize the state by using init_genrand(seed)
  22. or init_by_array(init_key, key_length).
  23. */
  24. /**
  25. @license
  26. mersenne-twister.js - https://gist.github.com/banksean/300494
  27. Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
  28. All rights reserved.
  29. Redistribution and use in source and binary forms, with or without
  30. modification, are permitted provided that the following conditions
  31. are met:
  32. 1. Redistributions of source code must retain the above copyright
  33. notice, this list of conditions and the following disclaimer.
  34. 2. Redistributions in binary form must reproduce the above copyright
  35. notice, this list of conditions and the following disclaimer in the
  36. documentation and/or other materials provided with the distribution.
  37. 3. The names of its contributors may not be used to endorse or promote
  38. products derived from this software without specific prior written
  39. permission.
  40. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  41. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  42. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  43. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  44. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  45. EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  46. PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  47. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  48. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  49. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  50. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51. */
  52. /*
  53. Any feedback is very welcome.
  54. http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
  55. email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
  56. */
  57. function MersenneTwister(seed) {
  58. if (seed == undefined) {
  59. seed = new Date().getTime();
  60. }
  61. /* Period parameters */
  62. this.N = 624;
  63. this.M = 397;
  64. this.MATRIX_A = 0x9908b0df; /* constant vector a */
  65. this.UPPER_MASK = 0x80000000; /* most significant w-r bits */
  66. this.LOWER_MASK = 0x7fffffff; /* least significant r bits */
  67. this.mt = new Array(this.N); /* the array for the state vector */
  68. this.mti=this.N+1; /* mti==N+1 means mt[N] is not initialized */
  69. this.init_genrand(seed);
  70. }
  71. /* initializes mt[N] with a seed */
  72. MersenneTwister.prototype.init_genrand = function(s) {
  73. this.mt[0] = s >>> 0;
  74. for (this.mti=1; this.mti<this.N; this.mti++) {
  75. var s = this.mt[this.mti-1] ^ (this.mt[this.mti-1] >>> 30);
  76. this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253)
  77. + this.mti;
  78. /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
  79. /* In the previous versions, MSBs of the seed affect */
  80. /* only MSBs of the array mt[]. */
  81. /* 2002/01/09 modified by Makoto Matsumoto */
  82. this.mt[this.mti] >>>= 0;
  83. /* for >32 bit machines */
  84. }
  85. };
  86. /* initialize by an array with array-length */
  87. /* init_key is the array for initializing keys */
  88. /* key_length is its length */
  89. /* slight change for C++, 2004/2/26 */
  90. //MersenneTwister.prototype.init_by_array = function(init_key, key_length) {
  91. // var i, j, k;
  92. // this.init_genrand(19650218);
  93. // i=1; j=0;
  94. // k = (this.N>key_length ? this.N : key_length);
  95. // for (; k; k--) {
  96. // var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30)
  97. // this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525)))
  98. // + init_key[j] + j; /* non linear */
  99. // this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */
  100. // i++; j++;
  101. // if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; }
  102. // if (j>=key_length) j=0;
  103. // }
  104. // for (k=this.N-1; k; k--) {
  105. // var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30);
  106. // this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941))
  107. // - i; /* non linear */
  108. // this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */
  109. // i++;
  110. // if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; }
  111. // }
  112. //
  113. // this.mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */
  114. //}
  115. /* generates a random number on [0,0xffffffff]-interval */
  116. MersenneTwister.prototype.genrand_int32 = function() {
  117. var y;
  118. var mag01 = new Array(0x0, this.MATRIX_A);
  119. /* mag01[x] = x * MATRIX_A for x=0,1 */
  120. if (this.mti >= this.N) { /* generate N words at one time */
  121. var kk;
  122. if (this.mti == this.N+1) /* if init_genrand() has not been called, */
  123. this.init_genrand(5489); /* a default initial seed is used */
  124. for (kk=0;kk<this.N-this.M;kk++) {
  125. y = (this.mt[kk]&this.UPPER_MASK)|(this.mt[kk+1]&this.LOWER_MASK);
  126. this.mt[kk] = this.mt[kk+this.M] ^ (y >>> 1) ^ mag01[y & 0x1];
  127. }
  128. for (;kk<this.N-1;kk++) {
  129. y = (this.mt[kk]&this.UPPER_MASK)|(this.mt[kk+1]&this.LOWER_MASK);
  130. this.mt[kk] = this.mt[kk+(this.M-this.N)] ^ (y >>> 1) ^ mag01[y & 0x1];
  131. }
  132. y = (this.mt[this.N-1]&this.UPPER_MASK)|(this.mt[0]&this.LOWER_MASK);
  133. this.mt[this.N-1] = this.mt[this.M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
  134. this.mti = 0;
  135. }
  136. y = this.mt[this.mti++];
  137. /* Tempering */
  138. y ^= (y >>> 11);
  139. y ^= (y << 7) & 0x9d2c5680;
  140. y ^= (y << 15) & 0xefc60000;
  141. y ^= (y >>> 18);
  142. return y >>> 0;
  143. };
  144. /* generates a random number on [0,0x7fffffff]-interval */
  145. //MersenneTwister.prototype.genrand_int31 = function() {
  146. // return (this.genrand_int32()>>>1);
  147. //}
  148. /* generates a random number on [0,1]-real-interval */
  149. //MersenneTwister.prototype.genrand_real1 = function() {
  150. // return this.genrand_int32()*(1.0/4294967295.0);
  151. // /* divided by 2^32-1 */
  152. //}
  153. /* generates a random number on [0,1)-real-interval */
  154. MersenneTwister.prototype.random = function() {
  155. return this.genrand_int32()*(1.0/4294967296.0);
  156. /* divided by 2^32 */
  157. };
  158. /**
  159. * Math functions.
  160. *
  161. * @exports CesiumMath
  162. * @alias Math
  163. */
  164. var CesiumMath = {};
  165. /**
  166. * 0.1
  167. * @type {Number}
  168. * @constant
  169. */
  170. CesiumMath.EPSILON1 = 0.1;
  171. /**
  172. * 0.01
  173. * @type {Number}
  174. * @constant
  175. */
  176. CesiumMath.EPSILON2 = 0.01;
  177. /**
  178. * 0.001
  179. * @type {Number}
  180. * @constant
  181. */
  182. CesiumMath.EPSILON3 = 0.001;
  183. /**
  184. * 0.0001
  185. * @type {Number}
  186. * @constant
  187. */
  188. CesiumMath.EPSILON4 = 0.0001;
  189. /**
  190. * 0.00001
  191. * @type {Number}
  192. * @constant
  193. */
  194. CesiumMath.EPSILON5 = 0.00001;
  195. /**
  196. * 0.000001
  197. * @type {Number}
  198. * @constant
  199. */
  200. CesiumMath.EPSILON6 = 0.000001;
  201. /**
  202. * 0.0000001
  203. * @type {Number}
  204. * @constant
  205. */
  206. CesiumMath.EPSILON7 = 0.0000001;
  207. /**
  208. * 0.00000001
  209. * @type {Number}
  210. * @constant
  211. */
  212. CesiumMath.EPSILON8 = 0.00000001;
  213. /**
  214. * 0.000000001
  215. * @type {Number}
  216. * @constant
  217. */
  218. CesiumMath.EPSILON9 = 0.000000001;
  219. /**
  220. * 0.0000000001
  221. * @type {Number}
  222. * @constant
  223. */
  224. CesiumMath.EPSILON10 = 0.0000000001;
  225. /**
  226. * 0.00000000001
  227. * @type {Number}
  228. * @constant
  229. */
  230. CesiumMath.EPSILON11 = 0.00000000001;
  231. /**
  232. * 0.000000000001
  233. * @type {Number}
  234. * @constant
  235. */
  236. CesiumMath.EPSILON12 = 0.000000000001;
  237. /**
  238. * 0.0000000000001
  239. * @type {Number}
  240. * @constant
  241. */
  242. CesiumMath.EPSILON13 = 0.0000000000001;
  243. /**
  244. * 0.00000000000001
  245. * @type {Number}
  246. * @constant
  247. */
  248. CesiumMath.EPSILON14 = 0.00000000000001;
  249. /**
  250. * 0.000000000000001
  251. * @type {Number}
  252. * @constant
  253. */
  254. CesiumMath.EPSILON15 = 0.000000000000001;
  255. /**
  256. * 0.0000000000000001
  257. * @type {Number}
  258. * @constant
  259. */
  260. CesiumMath.EPSILON16 = 0.0000000000000001;
  261. /**
  262. * 0.00000000000000001
  263. * @type {Number}
  264. * @constant
  265. */
  266. CesiumMath.EPSILON17 = 0.00000000000000001;
  267. /**
  268. * 0.000000000000000001
  269. * @type {Number}
  270. * @constant
  271. */
  272. CesiumMath.EPSILON18 = 0.000000000000000001;
  273. /**
  274. * 0.0000000000000000001
  275. * @type {Number}
  276. * @constant
  277. */
  278. CesiumMath.EPSILON19 = 0.0000000000000000001;
  279. /**
  280. * 0.00000000000000000001
  281. * @type {Number}
  282. * @constant
  283. */
  284. CesiumMath.EPSILON20 = 0.00000000000000000001;
  285. /**
  286. * 0.000000000000000000001
  287. * @type {Number}
  288. * @constant
  289. */
  290. CesiumMath.EPSILON21 = 0.000000000000000000001;
  291. /**
  292. * The gravitational parameter of the Earth in meters cubed
  293. * per second squared as defined by the WGS84 model: 3.986004418e14
  294. * @type {Number}
  295. * @constant
  296. */
  297. CesiumMath.GRAVITATIONALPARAMETER = 3.986004418e14;
  298. /**
  299. * Radius of the sun in meters: 6.955e8
  300. * @type {Number}
  301. * @constant
  302. */
  303. CesiumMath.SOLAR_RADIUS = 6.955e8;
  304. /**
  305. * The mean radius of the moon, according to the "Report of the IAU/IAG Working Group on
  306. * Cartographic Coordinates and Rotational Elements of the Planets and satellites: 2000",
  307. * Celestial Mechanics 82: 83-110, 2002.
  308. * @type {Number}
  309. * @constant
  310. */
  311. CesiumMath.LUNAR_RADIUS = 1737400.0;
  312. /**
  313. * 64 * 1024
  314. * @type {Number}
  315. * @constant
  316. */
  317. CesiumMath.SIXTY_FOUR_KILOBYTES = 64 * 1024;
  318. /**
  319. * 4 * 1024 * 1024 * 1024
  320. * @type {Number}
  321. * @constant
  322. */
  323. CesiumMath.FOUR_GIGABYTES = 4 * 1024 * 1024 * 1024;
  324. /**
  325. * Returns the sign of the value; 1 if the value is positive, -1 if the value is
  326. * negative, or 0 if the value is 0.
  327. *
  328. * @function
  329. * @param {Number} value The value to return the sign of.
  330. * @returns {Number} The sign of value.
  331. */
  332. CesiumMath.sign = when.defaultValue(Math.sign, function sign(value) {
  333. value = +value; // coerce to number
  334. if (value === 0 || value !== value) {
  335. // zero or NaN
  336. return value;
  337. }
  338. return value > 0 ? 1 : -1;
  339. });
  340. /**
  341. * Returns 1.0 if the given value is positive or zero, and -1.0 if it is negative.
  342. * This is similar to {@link CesiumMath#sign} except that returns 1.0 instead of
  343. * 0.0 when the input value is 0.0.
  344. * @param {Number} value The value to return the sign of.
  345. * @returns {Number} The sign of value.
  346. */
  347. CesiumMath.signNotZero = function (value) {
  348. return value < 0.0 ? -1.0 : 1.0;
  349. };
  350. /**
  351. * Converts a scalar value in the range [-1.0, 1.0] to a SNORM in the range [0, rangeMaximum]
  352. * @param {Number} value The scalar value in the range [-1.0, 1.0]
  353. * @param {Number} [rangeMaximum=255] The maximum value in the mapped range, 255 by default.
  354. * @returns {Number} A SNORM value, where 0 maps to -1.0 and rangeMaximum maps to 1.0.
  355. *
  356. * @see CesiumMath.fromSNorm
  357. */
  358. CesiumMath.toSNorm = function (value, rangeMaximum) {
  359. rangeMaximum = when.defaultValue(rangeMaximum, 255);
  360. return Math.round(
  361. (CesiumMath.clamp(value, -1.0, 1.0) * 0.5 + 0.5) * rangeMaximum
  362. );
  363. };
  364. /**
  365. * Converts a SNORM value in the range [0, rangeMaximum] to a scalar in the range [-1.0, 1.0].
  366. * @param {Number} value SNORM value in the range [0, rangeMaximum]
  367. * @param {Number} [rangeMaximum=255] The maximum value in the SNORM range, 255 by default.
  368. * @returns {Number} Scalar in the range [-1.0, 1.0].
  369. *
  370. * @see CesiumMath.toSNorm
  371. */
  372. CesiumMath.fromSNorm = function (value, rangeMaximum) {
  373. rangeMaximum = when.defaultValue(rangeMaximum, 255);
  374. return (
  375. (CesiumMath.clamp(value, 0.0, rangeMaximum) / rangeMaximum) * 2.0 - 1.0
  376. );
  377. };
  378. /**
  379. * Converts a scalar value in the range [rangeMinimum, rangeMaximum] to a scalar in the range [0.0, 1.0]
  380. * @param {Number} value The scalar value in the range [rangeMinimum, rangeMaximum]
  381. * @param {Number} rangeMinimum The minimum value in the mapped range.
  382. * @param {Number} rangeMaximum The maximum value in the mapped range.
  383. * @returns {Number} A scalar value, where rangeMinimum maps to 0.0 and rangeMaximum maps to 1.0.
  384. */
  385. CesiumMath.normalize = function (value, rangeMinimum, rangeMaximum) {
  386. rangeMaximum = Math.max(rangeMaximum - rangeMinimum, 0.0);
  387. return rangeMaximum === 0.0
  388. ? 0.0
  389. : CesiumMath.clamp((value - rangeMinimum) / rangeMaximum, 0.0, 1.0);
  390. };
  391. /**
  392. * Returns the hyperbolic sine of a number.
  393. * The hyperbolic sine of <em>value</em> is defined to be
  394. * (<em>e<sup>x</sup>&nbsp;-&nbsp;e<sup>-x</sup></em>)/2.0
  395. * where <i>e</i> is Euler's number, approximately 2.71828183.
  396. *
  397. * <p>Special cases:
  398. * <ul>
  399. * <li>If the argument is NaN, then the result is NaN.</li>
  400. *
  401. * <li>If the argument is infinite, then the result is an infinity
  402. * with the same sign as the argument.</li>
  403. *
  404. * <li>If the argument is zero, then the result is a zero with the
  405. * same sign as the argument.</li>
  406. * </ul>
  407. *</p>
  408. *
  409. * @function
  410. * @param {Number} value The number whose hyperbolic sine is to be returned.
  411. * @returns {Number} The hyperbolic sine of <code>value</code>.
  412. */
  413. CesiumMath.sinh = when.defaultValue(Math.sinh, function sinh(value) {
  414. return (Math.exp(value) - Math.exp(-value)) / 2.0;
  415. });
  416. /**
  417. * Returns the hyperbolic cosine of a number.
  418. * The hyperbolic cosine of <strong>value</strong> is defined to be
  419. * (<em>e<sup>x</sup>&nbsp;+&nbsp;e<sup>-x</sup></em>)/2.0
  420. * where <i>e</i> is Euler's number, approximately 2.71828183.
  421. *
  422. * <p>Special cases:
  423. * <ul>
  424. * <li>If the argument is NaN, then the result is NaN.</li>
  425. *
  426. * <li>If the argument is infinite, then the result is positive infinity.</li>
  427. *
  428. * <li>If the argument is zero, then the result is 1.0.</li>
  429. * </ul>
  430. *</p>
  431. *
  432. * @function
  433. * @param {Number} value The number whose hyperbolic cosine is to be returned.
  434. * @returns {Number} The hyperbolic cosine of <code>value</code>.
  435. */
  436. CesiumMath.cosh = when.defaultValue(Math.cosh, function cosh(value) {
  437. return (Math.exp(value) + Math.exp(-value)) / 2.0;
  438. });
  439. /**
  440. * Computes the linear interpolation of two values.
  441. *
  442. * @param {Number} p The start value to interpolate.
  443. * @param {Number} q The end value to interpolate.
  444. * @param {Number} time The time of interpolation generally in the range <code>[0.0, 1.0]</code>.
  445. * @returns {Number} The linearly interpolated value.
  446. *
  447. * @example
  448. * var n = Cesium.Math.lerp(0.0, 2.0, 0.5); // returns 1.0
  449. */
  450. CesiumMath.lerp = function (p, q, time) {
  451. return (1.0 - time) * p + time * q;
  452. };
  453. /**
  454. * pi
  455. *
  456. * @type {Number}
  457. * @constant
  458. */
  459. CesiumMath.PI = Math.PI;
  460. /**
  461. * 1/pi
  462. *
  463. * @type {Number}
  464. * @constant
  465. */
  466. CesiumMath.ONE_OVER_PI = 1.0 / Math.PI;
  467. /**
  468. * pi/2
  469. *
  470. * @type {Number}
  471. * @constant
  472. */
  473. CesiumMath.PI_OVER_TWO = Math.PI / 2.0;
  474. /**
  475. * pi/3
  476. *
  477. * @type {Number}
  478. * @constant
  479. */
  480. CesiumMath.PI_OVER_THREE = Math.PI / 3.0;
  481. /**
  482. * pi/4
  483. *
  484. * @type {Number}
  485. * @constant
  486. */
  487. CesiumMath.PI_OVER_FOUR = Math.PI / 4.0;
  488. /**
  489. * pi/6
  490. *
  491. * @type {Number}
  492. * @constant
  493. */
  494. CesiumMath.PI_OVER_SIX = Math.PI / 6.0;
  495. /**
  496. * 3pi/2
  497. *
  498. * @type {Number}
  499. * @constant
  500. */
  501. CesiumMath.THREE_PI_OVER_TWO = (3.0 * Math.PI) / 2.0;
  502. /**
  503. * 2pi
  504. *
  505. * @type {Number}
  506. * @constant
  507. */
  508. CesiumMath.TWO_PI = 2.0 * Math.PI;
  509. /**
  510. * 1/2pi
  511. *
  512. * @type {Number}
  513. * @constant
  514. */
  515. CesiumMath.ONE_OVER_TWO_PI = 1.0 / (2.0 * Math.PI);
  516. /**
  517. * The number of radians in a degree.
  518. *
  519. * @type {Number}
  520. * @constant
  521. */
  522. CesiumMath.RADIANS_PER_DEGREE = Math.PI / 180.0;
  523. /**
  524. * The number of degrees in a radian.
  525. *
  526. * @type {Number}
  527. * @constant
  528. */
  529. CesiumMath.DEGREES_PER_RADIAN = 180.0 / Math.PI;
  530. /**
  531. * The number of radians in an arc second.
  532. *
  533. * @type {Number}
  534. * @constant
  535. */
  536. CesiumMath.RADIANS_PER_ARCSECOND = CesiumMath.RADIANS_PER_DEGREE / 3600.0;
  537. /**
  538. * Converts degrees to radians.
  539. * @param {Number} degrees The angle to convert in degrees.
  540. * @returns {Number} The corresponding angle in radians.
  541. */
  542. CesiumMath.toRadians = function (degrees) {
  543. //>>includeStart('debug', pragmas.debug);
  544. if (!when.defined(degrees)) {
  545. throw new Check.DeveloperError("degrees is required.");
  546. }
  547. //>>includeEnd('debug');
  548. return degrees * CesiumMath.RADIANS_PER_DEGREE;
  549. };
  550. /**
  551. * Converts radians to degrees.
  552. * @param {Number} radians The angle to convert in radians.
  553. * @returns {Number} The corresponding angle in degrees.
  554. */
  555. CesiumMath.toDegrees = function (radians) {
  556. //>>includeStart('debug', pragmas.debug);
  557. if (!when.defined(radians)) {
  558. throw new Check.DeveloperError("radians is required.");
  559. }
  560. //>>includeEnd('debug');
  561. return radians * CesiumMath.DEGREES_PER_RADIAN;
  562. };
  563. /**
  564. * Converts a longitude value, in radians, to the range [<code>-Math.PI</code>, <code>Math.PI</code>).
  565. *
  566. * @param {Number} angle The longitude value, in radians, to convert to the range [<code>-Math.PI</code>, <code>Math.PI</code>).
  567. * @returns {Number} The equivalent longitude value in the range [<code>-Math.PI</code>, <code>Math.PI</code>).
  568. *
  569. * @example
  570. * // Convert 270 degrees to -90 degrees longitude
  571. * var longitude = Cesium.Math.convertLongitudeRange(Cesium.Math.toRadians(270.0));
  572. */
  573. CesiumMath.convertLongitudeRange = function (angle) {
  574. //>>includeStart('debug', pragmas.debug);
  575. if (!when.defined(angle)) {
  576. throw new Check.DeveloperError("angle is required.");
  577. }
  578. //>>includeEnd('debug');
  579. var twoPi = CesiumMath.TWO_PI;
  580. var simplified = angle - Math.floor(angle / twoPi) * twoPi;
  581. if (simplified < -Math.PI) {
  582. return simplified + twoPi;
  583. }
  584. if (simplified >= Math.PI) {
  585. return simplified - twoPi;
  586. }
  587. return simplified;
  588. };
  589. /**
  590. * Convenience function that clamps a latitude value, in radians, to the range [<code>-Math.PI/2</code>, <code>Math.PI/2</code>).
  591. * Useful for sanitizing data before use in objects requiring correct range.
  592. *
  593. * @param {Number} angle The latitude value, in radians, to clamp to the range [<code>-Math.PI/2</code>, <code>Math.PI/2</code>).
  594. * @returns {Number} The latitude value clamped to the range [<code>-Math.PI/2</code>, <code>Math.PI/2</code>).
  595. *
  596. * @example
  597. * // Clamp 108 degrees latitude to 90 degrees latitude
  598. * var latitude = Cesium.Math.clampToLatitudeRange(Cesium.Math.toRadians(108.0));
  599. */
  600. CesiumMath.clampToLatitudeRange = function (angle) {
  601. //>>includeStart('debug', pragmas.debug);
  602. if (!when.defined(angle)) {
  603. throw new Check.DeveloperError("angle is required.");
  604. }
  605. //>>includeEnd('debug');
  606. return CesiumMath.clamp(
  607. angle,
  608. -1 * CesiumMath.PI_OVER_TWO,
  609. CesiumMath.PI_OVER_TWO
  610. );
  611. };
  612. /**
  613. * Produces an angle in the range -Pi <= angle <= Pi which is equivalent to the provided angle.
  614. *
  615. * @param {Number} angle in radians
  616. * @returns {Number} The angle in the range [<code>-CesiumMath.PI</code>, <code>CesiumMath.PI</code>].
  617. */
  618. CesiumMath.negativePiToPi = function (angle) {
  619. //>>includeStart('debug', pragmas.debug);
  620. if (!when.defined(angle)) {
  621. throw new Check.DeveloperError("angle is required.");
  622. }
  623. //>>includeEnd('debug');
  624. return CesiumMath.zeroToTwoPi(angle + CesiumMath.PI) - CesiumMath.PI;
  625. };
  626. /**
  627. * Produces an angle in the range 0 <= angle <= 2Pi which is equivalent to the provided angle.
  628. *
  629. * @param {Number} angle in radians
  630. * @returns {Number} The angle in the range [0, <code>CesiumMath.TWO_PI</code>].
  631. */
  632. CesiumMath.zeroToTwoPi = function (angle) {
  633. //>>includeStart('debug', pragmas.debug);
  634. if (!when.defined(angle)) {
  635. throw new Check.DeveloperError("angle is required.");
  636. }
  637. //>>includeEnd('debug');
  638. var mod = CesiumMath.mod(angle, CesiumMath.TWO_PI);
  639. if (
  640. Math.abs(mod) < CesiumMath.EPSILON14 &&
  641. Math.abs(angle) > CesiumMath.EPSILON14
  642. ) {
  643. return CesiumMath.TWO_PI;
  644. }
  645. return mod;
  646. };
  647. /**
  648. * The modulo operation that also works for negative dividends.
  649. *
  650. * @param {Number} m The dividend.
  651. * @param {Number} n The divisor.
  652. * @returns {Number} The remainder.
  653. */
  654. CesiumMath.mod = function (m, n) {
  655. //>>includeStart('debug', pragmas.debug);
  656. if (!when.defined(m)) {
  657. throw new Check.DeveloperError("m is required.");
  658. }
  659. if (!when.defined(n)) {
  660. throw new Check.DeveloperError("n is required.");
  661. }
  662. //>>includeEnd('debug');
  663. return ((m % n) + n) % n;
  664. };
  665. /**
  666. * Determines if two values are equal using an absolute or relative tolerance test. This is useful
  667. * to avoid problems due to roundoff error when comparing floating-point values directly. The values are
  668. * first compared using an absolute tolerance test. If that fails, a relative tolerance test is performed.
  669. * Use this test if you are unsure of the magnitudes of left and right.
  670. *
  671. * @param {Number} left The first value to compare.
  672. * @param {Number} right The other value to compare.
  673. * @param {Number} [relativeEpsilon=0] The maximum inclusive delta between <code>left</code> and <code>right</code> for the relative tolerance test.
  674. * @param {Number} [absoluteEpsilon=relativeEpsilon] The maximum inclusive delta between <code>left</code> and <code>right</code> for the absolute tolerance test.
  675. * @returns {Boolean} <code>true</code> if the values are equal within the epsilon; otherwise, <code>false</code>.
  676. *
  677. * @example
  678. * var a = Cesium.Math.equalsEpsilon(0.0, 0.01, Cesium.Math.EPSILON2); // true
  679. * var b = Cesium.Math.equalsEpsilon(0.0, 0.1, Cesium.Math.EPSILON2); // false
  680. * var c = Cesium.Math.equalsEpsilon(3699175.1634344, 3699175.2, Cesium.Math.EPSILON7); // true
  681. * var d = Cesium.Math.equalsEpsilon(3699175.1634344, 3699175.2, Cesium.Math.EPSILON9); // false
  682. */
  683. CesiumMath.equalsEpsilon = function (
  684. left,
  685. right,
  686. relativeEpsilon,
  687. absoluteEpsilon
  688. ) {
  689. //>>includeStart('debug', pragmas.debug);
  690. if (!when.defined(left)) {
  691. throw new Check.DeveloperError("left is required.");
  692. }
  693. if (!when.defined(right)) {
  694. throw new Check.DeveloperError("right is required.");
  695. }
  696. //>>includeEnd('debug');
  697. relativeEpsilon = when.defaultValue(relativeEpsilon, 0.0);
  698. absoluteEpsilon = when.defaultValue(absoluteEpsilon, relativeEpsilon);
  699. var absDiff = Math.abs(left - right);
  700. return (
  701. absDiff <= absoluteEpsilon ||
  702. absDiff <= relativeEpsilon * Math.max(Math.abs(left), Math.abs(right))
  703. );
  704. };
  705. /**
  706. * Determines if the left value is less than the right value. If the two values are within
  707. * <code>absoluteEpsilon</code> of each other, they are considered equal and this function returns false.
  708. *
  709. * @param {Number} left The first number to compare.
  710. * @param {Number} right The second number to compare.
  711. * @param {Number} absoluteEpsilon The absolute epsilon to use in comparison.
  712. * @returns {Boolean} <code>true</code> if <code>left</code> is less than <code>right</code> by more than
  713. * <code>absoluteEpsilon<code>. <code>false</code> if <code>left</code> is greater or if the two
  714. * values are nearly equal.
  715. */
  716. CesiumMath.lessThan = function (left, right, absoluteEpsilon) {
  717. //>>includeStart('debug', pragmas.debug);
  718. if (!when.defined(left)) {
  719. throw new Check.DeveloperError("first is required.");
  720. }
  721. if (!when.defined(right)) {
  722. throw new Check.DeveloperError("second is required.");
  723. }
  724. if (!when.defined(absoluteEpsilon)) {
  725. throw new Check.DeveloperError("relativeEpsilon is required.");
  726. }
  727. //>>includeEnd('debug');
  728. return left - right < -absoluteEpsilon;
  729. };
  730. /**
  731. * Determines if the left value is less than or equal to the right value. If the two values are within
  732. * <code>absoluteEpsilon</code> of each other, they are considered equal and this function returns true.
  733. *
  734. * @param {Number} left The first number to compare.
  735. * @param {Number} right The second number to compare.
  736. * @param {Number} absoluteEpsilon The absolute epsilon to use in comparison.
  737. * @returns {Boolean} <code>true</code> if <code>left</code> is less than <code>right</code> or if the
  738. * the values are nearly equal.
  739. */
  740. CesiumMath.lessThanOrEquals = function (left, right, absoluteEpsilon) {
  741. //>>includeStart('debug', pragmas.debug);
  742. if (!when.defined(left)) {
  743. throw new Check.DeveloperError("first is required.");
  744. }
  745. if (!when.defined(right)) {
  746. throw new Check.DeveloperError("second is required.");
  747. }
  748. if (!when.defined(absoluteEpsilon)) {
  749. throw new Check.DeveloperError("relativeEpsilon is required.");
  750. }
  751. //>>includeEnd('debug');
  752. return left - right < absoluteEpsilon;
  753. };
  754. /**
  755. * Determines if the left value is greater the right value. If the two values are within
  756. * <code>absoluteEpsilon</code> of each other, they are considered equal and this function returns false.
  757. *
  758. * @param {Number} left The first number to compare.
  759. * @param {Number} right The second number to compare.
  760. * @param {Number} absoluteEpsilon The absolute epsilon to use in comparison.
  761. * @returns {Boolean} <code>true</code> if <code>left</code> is greater than <code>right</code> by more than
  762. * <code>absoluteEpsilon<code>. <code>false</code> if <code>left</code> is less or if the two
  763. * values are nearly equal.
  764. */
  765. CesiumMath.greaterThan = function (left, right, absoluteEpsilon) {
  766. //>>includeStart('debug', pragmas.debug);
  767. if (!when.defined(left)) {
  768. throw new Check.DeveloperError("first is required.");
  769. }
  770. if (!when.defined(right)) {
  771. throw new Check.DeveloperError("second is required.");
  772. }
  773. if (!when.defined(absoluteEpsilon)) {
  774. throw new Check.DeveloperError("relativeEpsilon is required.");
  775. }
  776. //>>includeEnd('debug');
  777. return left - right > absoluteEpsilon;
  778. };
  779. /**
  780. * Determines if the left value is greater than or equal to the right value. If the two values are within
  781. * <code>absoluteEpsilon</code> of each other, they are considered equal and this function returns true.
  782. *
  783. * @param {Number} left The first number to compare.
  784. * @param {Number} right The second number to compare.
  785. * @param {Number} absoluteEpsilon The absolute epsilon to use in comparison.
  786. * @returns {Boolean} <code>true</code> if <code>left</code> is greater than <code>right</code> or if the
  787. * the values are nearly equal.
  788. */
  789. CesiumMath.greaterThanOrEquals = function (left, right, absoluteEpsilon) {
  790. //>>includeStart('debug', pragmas.debug);
  791. if (!when.defined(left)) {
  792. throw new Check.DeveloperError("first is required.");
  793. }
  794. if (!when.defined(right)) {
  795. throw new Check.DeveloperError("second is required.");
  796. }
  797. if (!when.defined(absoluteEpsilon)) {
  798. throw new Check.DeveloperError("relativeEpsilon is required.");
  799. }
  800. //>>includeEnd('debug');
  801. return left - right > -absoluteEpsilon;
  802. };
  803. var factorials = [1];
  804. /**
  805. * Computes the factorial of the provided number.
  806. *
  807. * @param {Number} n The number whose factorial is to be computed.
  808. * @returns {Number} The factorial of the provided number or undefined if the number is less than 0.
  809. *
  810. * @exception {DeveloperError} A number greater than or equal to 0 is required.
  811. *
  812. *
  813. * @example
  814. * //Compute 7!, which is equal to 5040
  815. * var computedFactorial = Cesium.Math.factorial(7);
  816. *
  817. * @see {@link http://en.wikipedia.org/wiki/Factorial|Factorial on Wikipedia}
  818. */
  819. CesiumMath.factorial = function (n) {
  820. //>>includeStart('debug', pragmas.debug);
  821. if (typeof n !== "number" || n < 0) {
  822. throw new Check.DeveloperError(
  823. "A number greater than or equal to 0 is required."
  824. );
  825. }
  826. //>>includeEnd('debug');
  827. var length = factorials.length;
  828. if (n >= length) {
  829. var sum = factorials[length - 1];
  830. for (var i = length; i <= n; i++) {
  831. var next = sum * i;
  832. factorials.push(next);
  833. sum = next;
  834. }
  835. }
  836. return factorials[n];
  837. };
  838. /**
  839. * Increments a number with a wrapping to a minimum value if the number exceeds the maximum value.
  840. *
  841. * @param {Number} [n] The number to be incremented.
  842. * @param {Number} [maximumValue] The maximum incremented value before rolling over to the minimum value.
  843. * @param {Number} [minimumValue=0.0] The number reset to after the maximum value has been exceeded.
  844. * @returns {Number} The incremented number.
  845. *
  846. * @exception {DeveloperError} Maximum value must be greater than minimum value.
  847. *
  848. * @example
  849. * var n = Cesium.Math.incrementWrap(5, 10, 0); // returns 6
  850. * var n = Cesium.Math.incrementWrap(10, 10, 0); // returns 0
  851. */
  852. CesiumMath.incrementWrap = function (n, maximumValue, minimumValue) {
  853. minimumValue = when.defaultValue(minimumValue, 0.0);
  854. //>>includeStart('debug', pragmas.debug);
  855. if (!when.defined(n)) {
  856. throw new Check.DeveloperError("n is required.");
  857. }
  858. if (maximumValue <= minimumValue) {
  859. throw new Check.DeveloperError("maximumValue must be greater than minimumValue.");
  860. }
  861. //>>includeEnd('debug');
  862. ++n;
  863. if (n > maximumValue) {
  864. n = minimumValue;
  865. }
  866. return n;
  867. };
  868. /**
  869. * Determines if a positive integer is a power of two.
  870. *
  871. * @param {Number} n The positive integer to test.
  872. * @returns {Boolean} <code>true</code> if the number if a power of two; otherwise, <code>false</code>.
  873. *
  874. * @exception {DeveloperError} A number greater than or equal to 0 is required.
  875. *
  876. * @example
  877. * var t = Cesium.Math.isPowerOfTwo(16); // true
  878. * var f = Cesium.Math.isPowerOfTwo(20); // false
  879. */
  880. CesiumMath.isPowerOfTwo = function (n) {
  881. //>>includeStart('debug', pragmas.debug);
  882. if (typeof n !== "number" || n < 0) {
  883. throw new Check.DeveloperError(
  884. "A number greater than or equal to 0 is required."
  885. );
  886. }
  887. //>>includeEnd('debug');
  888. return n !== 0 && (n & (n - 1)) === 0;
  889. };
  890. /**
  891. * Computes the next power-of-two integer greater than or equal to the provided positive integer.
  892. *
  893. * @param {Number} n The positive integer to test.
  894. * @returns {Number} The next power-of-two integer.
  895. *
  896. * @exception {DeveloperError} A number greater than or equal to 0 is required.
  897. *
  898. * @example
  899. * var n = Cesium.Math.nextPowerOfTwo(29); // 32
  900. * var m = Cesium.Math.nextPowerOfTwo(32); // 32
  901. */
  902. CesiumMath.nextPowerOfTwo = function (n) {
  903. //>>includeStart('debug', pragmas.debug);
  904. if (typeof n !== "number" || n < 0) {
  905. throw new Check.DeveloperError(
  906. "A number greater than or equal to 0 is required."
  907. );
  908. }
  909. //>>includeEnd('debug');
  910. // From http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
  911. --n;
  912. n |= n >> 1;
  913. n |= n >> 2;
  914. n |= n >> 4;
  915. n |= n >> 8;
  916. n |= n >> 16;
  917. ++n;
  918. return n;
  919. };
  920. /**
  921. * Constraint a value to lie between two values.
  922. *
  923. * @param {Number} value The value to constrain.
  924. * @param {Number} min The minimum value.
  925. * @param {Number} max The maximum value.
  926. * @returns {Number} The value clamped so that min <= value <= max.
  927. */
  928. CesiumMath.clamp = function (value, min, max) {
  929. //>>includeStart('debug', pragmas.debug);
  930. if (!when.defined(value)) {
  931. throw new Check.DeveloperError("value is required");
  932. }
  933. if (!when.defined(min)) {
  934. throw new Check.DeveloperError("min is required.");
  935. }
  936. if (!when.defined(max)) {
  937. throw new Check.DeveloperError("max is required.");
  938. }
  939. //>>includeEnd('debug');
  940. return value < min ? min : value > max ? max : value;
  941. };
  942. var randomNumberGenerator = new MersenneTwister();
  943. /**
  944. * Sets the seed used by the random number generator
  945. * in {@link CesiumMath#nextRandomNumber}.
  946. *
  947. * @param {Number} seed An integer used as the seed.
  948. */
  949. CesiumMath.setRandomNumberSeed = function (seed) {
  950. //>>includeStart('debug', pragmas.debug);
  951. if (!when.defined(seed)) {
  952. throw new Check.DeveloperError("seed is required.");
  953. }
  954. //>>includeEnd('debug');
  955. randomNumberGenerator = new MersenneTwister(seed);
  956. };
  957. /**
  958. * Generates a random floating point number in the range of [0.0, 1.0)
  959. * using a Mersenne twister.
  960. *
  961. * @returns {Number} A random number in the range of [0.0, 1.0).
  962. *
  963. * @see CesiumMath.setRandomNumberSeed
  964. * @see {@link http://en.wikipedia.org/wiki/Mersenne_twister|Mersenne twister on Wikipedia}
  965. */
  966. CesiumMath.nextRandomNumber = function () {
  967. return randomNumberGenerator.random();
  968. };
  969. /**
  970. * Generates a random number between two numbers.
  971. *
  972. * @param {Number} min The minimum value.
  973. * @param {Number} max The maximum value.
  974. * @returns {Number} A random number between the min and max.
  975. */
  976. CesiumMath.randomBetween = function (min, max) {
  977. return CesiumMath.nextRandomNumber() * (max - min) + min;
  978. };
  979. /**
  980. * Computes <code>Math.acos(value)</code>, but first clamps <code>value</code> to the range [-1.0, 1.0]
  981. * so that the function will never return NaN.
  982. *
  983. * @param {Number} value The value for which to compute acos.
  984. * @returns {Number} The acos of the value if the value is in the range [-1.0, 1.0], or the acos of -1.0 or 1.0,
  985. * whichever is closer, if the value is outside the range.
  986. */
  987. CesiumMath.acosClamped = function (value) {
  988. //>>includeStart('debug', pragmas.debug);
  989. if (!when.defined(value)) {
  990. throw new Check.DeveloperError("value is required.");
  991. }
  992. //>>includeEnd('debug');
  993. return Math.acos(CesiumMath.clamp(value, -1.0, 1.0));
  994. };
  995. /**
  996. * Computes <code>Math.asin(value)</code>, but first clamps <code>value</code> to the range [-1.0, 1.0]
  997. * so that the function will never return NaN.
  998. *
  999. * @param {Number} value The value for which to compute asin.
  1000. * @returns {Number} The asin of the value if the value is in the range [-1.0, 1.0], or the asin of -1.0 or 1.0,
  1001. * whichever is closer, if the value is outside the range.
  1002. */
  1003. CesiumMath.asinClamped = function (value) {
  1004. //>>includeStart('debug', pragmas.debug);
  1005. if (!when.defined(value)) {
  1006. throw new Check.DeveloperError("value is required.");
  1007. }
  1008. //>>includeEnd('debug');
  1009. return Math.asin(CesiumMath.clamp(value, -1.0, 1.0));
  1010. };
  1011. /**
  1012. * Finds the chord length between two points given the circle's radius and the angle between the points.
  1013. *
  1014. * @param {Number} angle The angle between the two points.
  1015. * @param {Number} radius The radius of the circle.
  1016. * @returns {Number} The chord length.
  1017. */
  1018. CesiumMath.chordLength = function (angle, radius) {
  1019. //>>includeStart('debug', pragmas.debug);
  1020. if (!when.defined(angle)) {
  1021. throw new Check.DeveloperError("angle is required.");
  1022. }
  1023. if (!when.defined(radius)) {
  1024. throw new Check.DeveloperError("radius is required.");
  1025. }
  1026. //>>includeEnd('debug');
  1027. return 2.0 * radius * Math.sin(angle * 0.5);
  1028. };
  1029. /**
  1030. * Finds the logarithm of a number to a base.
  1031. *
  1032. * @param {Number} number The number.
  1033. * @param {Number} base The base.
  1034. * @returns {Number} The result.
  1035. */
  1036. CesiumMath.logBase = function (number, base) {
  1037. //>>includeStart('debug', pragmas.debug);
  1038. if (!when.defined(number)) {
  1039. throw new Check.DeveloperError("number is required.");
  1040. }
  1041. if (!when.defined(base)) {
  1042. throw new Check.DeveloperError("base is required.");
  1043. }
  1044. //>>includeEnd('debug');
  1045. return Math.log(number) / Math.log(base);
  1046. };
  1047. /**
  1048. * Finds the cube root of a number.
  1049. * Returns NaN if <code>number</code> is not provided.
  1050. *
  1051. * @function
  1052. * @param {Number} [number] The number.
  1053. * @returns {Number} The result.
  1054. */
  1055. CesiumMath.cbrt = when.defaultValue(Math.cbrt, function cbrt(number) {
  1056. var result = Math.pow(Math.abs(number), 1.0 / 3.0);
  1057. return number < 0.0 ? -result : result;
  1058. });
  1059. /**
  1060. * Finds the base 2 logarithm of a number.
  1061. *
  1062. * @function
  1063. * @param {Number} number The number.
  1064. * @returns {Number} The result.
  1065. */
  1066. CesiumMath.log2 = when.defaultValue(Math.log2, function log2(number) {
  1067. return Math.log(number) * Math.LOG2E;
  1068. });
  1069. /**
  1070. * @private
  1071. */
  1072. CesiumMath.fog = function (distanceToCamera, density) {
  1073. var scalar = distanceToCamera * density;
  1074. return 1.0 - Math.exp(-(scalar * scalar));
  1075. };
  1076. /**
  1077. * Computes a fast approximation of Atan for input in the range [-1, 1].
  1078. *
  1079. * Based on Michal Drobot's approximation from ShaderFastLibs,
  1080. * which in turn is based on "Efficient approximations for the arctangent function,"
  1081. * Rajan, S. Sichun Wang Inkol, R. Joyal, A., May 2006.
  1082. * Adapted from ShaderFastLibs under MIT License.
  1083. *
  1084. * @param {Number} x An input number in the range [-1, 1]
  1085. * @returns {Number} An approximation of atan(x)
  1086. */
  1087. CesiumMath.fastApproximateAtan = function (x) {
  1088. //>>includeStart('debug', pragmas.debug);
  1089. Check.Check.typeOf.number("x", x);
  1090. //>>includeEnd('debug');
  1091. return x * (-0.1784 * Math.abs(x) - 0.0663 * x * x + 1.0301);
  1092. };
  1093. /**
  1094. * Computes a fast approximation of Atan2(x, y) for arbitrary input scalars.
  1095. *
  1096. * Range reduction math based on nvidia's cg reference implementation: http://developer.download.nvidia.com/cg/atan2.html
  1097. *
  1098. * @param {Number} x An input number that isn't zero if y is zero.
  1099. * @param {Number} y An input number that isn't zero if x is zero.
  1100. * @returns {Number} An approximation of atan2(x, y)
  1101. */
  1102. CesiumMath.fastApproximateAtan2 = function (x, y) {
  1103. //>>includeStart('debug', pragmas.debug);
  1104. Check.Check.typeOf.number("x", x);
  1105. Check.Check.typeOf.number("y", y);
  1106. //>>includeEnd('debug');
  1107. // atan approximations are usually only reliable over [-1, 1]
  1108. // So reduce the range by flipping whether x or y is on top based on which is bigger.
  1109. var opposite;
  1110. var adjacent;
  1111. var t = Math.abs(x); // t used as swap and atan result.
  1112. opposite = Math.abs(y);
  1113. adjacent = Math.max(t, opposite);
  1114. opposite = Math.min(t, opposite);
  1115. var oppositeOverAdjacent = opposite / adjacent;
  1116. //>>includeStart('debug', pragmas.debug);
  1117. if (isNaN(oppositeOverAdjacent)) {
  1118. throw new Check.DeveloperError("either x or y must be nonzero");
  1119. }
  1120. //>>includeEnd('debug');
  1121. t = CesiumMath.fastApproximateAtan(oppositeOverAdjacent);
  1122. // Undo range reduction
  1123. t = Math.abs(y) > Math.abs(x) ? CesiumMath.PI_OVER_TWO - t : t;
  1124. t = x < 0.0 ? CesiumMath.PI - t : t;
  1125. t = y < 0.0 ? -t : t;
  1126. return t;
  1127. };
  1128. exports.CesiumMath = CesiumMath;
  1129. });