Mathf.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. using System;
  2. namespace UnityEngine
  3. {
  4. public static class Mathf
  5. {
  6. public const float Epsilon = 0.00001F;
  7. /// <summary>
  8. /// <para>Returns the sine of angle f.</para>
  9. /// </summary>
  10. /// <param name="f">The input angle, in radians.</param>
  11. /// <returns>
  12. /// <para>The return value between -1 and +1.</para>
  13. /// </returns>
  14. public static float Sin(float f)
  15. {
  16. return (float) Math.Sin((double) f);
  17. }
  18. /// <summary>
  19. /// <para>Returns the cosine of angle f.</para>
  20. /// </summary>
  21. /// <param name="f">The input angle, in radians.</param>
  22. /// <returns>
  23. /// <para>The return value between -1 and 1.</para>
  24. /// </returns>
  25. public static float Cos(float f)
  26. {
  27. return (float) Math.Cos((double) f);
  28. }
  29. /// <summary>
  30. /// <para>Returns the tangent of angle f in radians.</para>
  31. /// </summary>
  32. /// <param name="f"></param>
  33. public static float Tan(float f)
  34. {
  35. return (float) Math.Tan((double) f);
  36. }
  37. /// <summary>
  38. /// <para>Returns the arc-sine of f - the angle in radians whose sine is f.</para>
  39. /// </summary>
  40. /// <param name="f"></param>
  41. public static float Asin(float f)
  42. {
  43. return (float) Math.Asin((double) f);
  44. }
  45. /// <summary>
  46. /// <para>Returns the arc-cosine of f - the angle in radians whose cosine is f.</para>
  47. /// </summary>
  48. /// <param name="f"></param>
  49. public static float Acos(float f)
  50. {
  51. return (float) Math.Acos((double) f);
  52. }
  53. /// <summary>
  54. /// <para>Returns the arc-tangent of f - the angle in radians whose tangent is f.</para>
  55. /// </summary>
  56. /// <param name="f"></param>
  57. public static float Atan(float f)
  58. {
  59. return (float) Math.Atan((double) f);
  60. }
  61. /// <summary>
  62. /// <para>Returns the angle in radians whose Tan is y/x.</para>
  63. /// </summary>
  64. /// <param name="y"></param>
  65. /// <param name="x"></param>
  66. public static float Atan2(float y, float x)
  67. {
  68. return (float) Math.Atan2((double) y, (double) x);
  69. }
  70. /// <summary>
  71. /// <para>Returns square root of f.</para>
  72. /// </summary>
  73. /// <param name="f"></param>
  74. public static float Sqrt(float f)
  75. {
  76. return (float) Math.Sqrt((double) f);
  77. }
  78. /// <summary>
  79. /// <para>Returns the absolute value of f.</para>
  80. /// </summary>
  81. /// <param name="f"></param>
  82. public static float Abs(float f)
  83. {
  84. return Math.Abs(f);
  85. }
  86. /// <summary>
  87. /// <para>Returns the absolute value of value.</para>
  88. /// </summary>
  89. /// <param name="value"></param>
  90. public static int Abs(int value)
  91. {
  92. return Math.Abs(value);
  93. }
  94. /// <summary>
  95. /// <para>Returns the smallest of two or more values.</para>
  96. /// </summary>
  97. /// <param name="a"></param>
  98. /// <param name="b"></param>
  99. /// <param name="values"></param>
  100. public static float Min(float a, float b)
  101. {
  102. return (double) a >= (double) b? b : a;
  103. }
  104. /// <summary>
  105. /// <para>Returns the smallest of two or more values.</para>
  106. /// </summary>
  107. /// <param name="a"></param>
  108. /// <param name="b"></param>
  109. /// <param name="values"></param>
  110. public static float Min(params float[] values)
  111. {
  112. int length = values.Length;
  113. if (length == 0)
  114. return 0.0f;
  115. float num = values[0];
  116. for (int index = 1; index < length; ++index)
  117. {
  118. if ((double) values[index] < (double) num)
  119. num = values[index];
  120. }
  121. return num;
  122. }
  123. /// <summary>
  124. /// <para>Returns the smallest of two or more values.</para>
  125. /// </summary>
  126. /// <param name="a"></param>
  127. /// <param name="b"></param>
  128. /// <param name="values"></param>
  129. public static int Min(int a, int b)
  130. {
  131. return a >= b? b : a;
  132. }
  133. /// <summary>
  134. /// <para>Returns the smallest of two or more values.</para>
  135. /// </summary>
  136. /// <param name="a"></param>
  137. /// <param name="b"></param>
  138. /// <param name="values"></param>
  139. public static int Min(params int[] values)
  140. {
  141. int length = values.Length;
  142. if (length == 0)
  143. return 0;
  144. int num = values[0];
  145. for (int index = 1; index < length; ++index)
  146. {
  147. if (values[index] < num)
  148. num = values[index];
  149. }
  150. return num;
  151. }
  152. /// <summary>
  153. /// <para>Returns largest of two or more values.</para>
  154. /// </summary>
  155. /// <param name="a"></param>
  156. /// <param name="b"></param>
  157. /// <param name="values"></param>
  158. public static float Max(float a, float b)
  159. {
  160. return (double) a <= (double) b? b : a;
  161. }
  162. /// <summary>
  163. /// <para>Returns largest of two or more values.</para>
  164. /// </summary>
  165. /// <param name="a"></param>
  166. /// <param name="b"></param>
  167. /// <param name="values"></param>
  168. public static float Max(params float[] values)
  169. {
  170. int length = values.Length;
  171. if (length == 0)
  172. return 0.0f;
  173. float num = values[0];
  174. for (int index = 1; index < length; ++index)
  175. {
  176. if ((double) values[index] > (double) num)
  177. num = values[index];
  178. }
  179. return num;
  180. }
  181. /// <summary>
  182. /// <para>Returns the largest of two or more values.</para>
  183. /// </summary>
  184. /// <param name="a"></param>
  185. /// <param name="b"></param>
  186. /// <param name="values"></param>
  187. public static int Max(int a, int b)
  188. {
  189. return a <= b? b : a;
  190. }
  191. /// <summary>
  192. /// <para>Returns the largest of two or more values.</para>
  193. /// </summary>
  194. /// <param name="a"></param>
  195. /// <param name="b"></param>
  196. /// <param name="values"></param>
  197. public static int Max(params int[] values)
  198. {
  199. int length = values.Length;
  200. if (length == 0)
  201. return 0;
  202. int num = values[0];
  203. for (int index = 1; index < length; ++index)
  204. {
  205. if (values[index] > num)
  206. num = values[index];
  207. }
  208. return num;
  209. }
  210. /// <summary>
  211. /// <para>Returns f raised to power p.</para>
  212. /// </summary>
  213. /// <param name="f"></param>
  214. /// <param name="p"></param>
  215. public static float Pow(float f, float p)
  216. {
  217. return (float) Math.Pow((double) f, (double) p);
  218. }
  219. /// <summary>
  220. /// <para>Returns e raised to the specified power.</para>
  221. /// </summary>
  222. /// <param name="power"></param>
  223. public static float Exp(float power)
  224. {
  225. return (float) Math.Exp((double) power);
  226. }
  227. /// <summary>
  228. /// <para>Returns the logarithm of a specified number in a specified base.</para>
  229. /// </summary>
  230. /// <param name="f"></param>
  231. /// <param name="p"></param>
  232. public static float Log(float f, float p)
  233. {
  234. return (float) Math.Log((double) f, (double) p);
  235. }
  236. /// <summary>
  237. /// <para>Returns the natural (base e) logarithm of a specified number.</para>
  238. /// </summary>
  239. /// <param name="f"></param>
  240. public static float Log(float f)
  241. {
  242. return (float) Math.Log((double) f);
  243. }
  244. /// <summary>
  245. /// <para>Returns the base 10 logarithm of a specified number.</para>
  246. /// </summary>
  247. /// <param name="f"></param>
  248. public static float Log10(float f)
  249. {
  250. return (float) Math.Log10((double) f);
  251. }
  252. /// <summary>
  253. /// <para>Returns the smallest integer greater to or equal to f.</para>
  254. /// </summary>
  255. /// <param name="f"></param>
  256. public static float Ceil(float f)
  257. {
  258. return (float) Math.Ceiling((double) f);
  259. }
  260. /// <summary>
  261. /// <para>Returns the largest integer smaller to or equal to f.</para>
  262. /// </summary>
  263. /// <param name="f"></param>
  264. public static float Floor(float f)
  265. {
  266. return (float) Math.Floor((double) f);
  267. }
  268. /// <summary>
  269. /// <para>Returns f rounded to the nearest integer.</para>
  270. /// </summary>
  271. /// <param name="f"></param>
  272. public static float Round(float f)
  273. {
  274. return (float) Math.Round((double) f);
  275. }
  276. /// <summary>
  277. /// <para>Returns the smallest integer greater to or equal to f.</para>
  278. /// </summary>
  279. /// <param name="f"></param>
  280. public static int CeilToInt(float f)
  281. {
  282. return (int) Math.Ceiling((double) f);
  283. }
  284. /// <summary>
  285. /// <para>Returns the largest integer smaller to or equal to f.</para>
  286. /// </summary>
  287. /// <param name="f"></param>
  288. public static int FloorToInt(float f)
  289. {
  290. return (int) Math.Floor((double) f);
  291. }
  292. /// <summary>
  293. /// <para>Returns f rounded to the nearest integer.</para>
  294. /// </summary>
  295. /// <param name="f"></param>
  296. public static int RoundToInt(float f)
  297. {
  298. return (int) Math.Round((double) f);
  299. }
  300. /// <summary>
  301. /// <para>Returns the sign of f.</para>
  302. /// </summary>
  303. /// <param name="f"></param>
  304. public static float Sign(float f)
  305. {
  306. return (double) f < 0.0? -1f : 1f;
  307. }
  308. /// <summary>
  309. /// <para>Clamps a value between a minimum float and maximum float value.</para>
  310. /// </summary>
  311. /// <param name="value"></param>
  312. /// <param name="min"></param>
  313. /// <param name="max"></param>
  314. public static float Clamp(float value, float min, float max)
  315. {
  316. if ((double) value < (double) min)
  317. value = min;
  318. else if ((double) value > (double) max)
  319. value = max;
  320. return value;
  321. }
  322. /// <summary>
  323. /// <para>Clamps value between min and max and returns value.</para>
  324. /// </summary>
  325. /// <param name="value"></param>
  326. /// <param name="min"></param>
  327. /// <param name="max"></param>
  328. public static int Clamp(int value, int min, int max)
  329. {
  330. if (value < min)
  331. value = min;
  332. else if (value > max)
  333. value = max;
  334. return value;
  335. }
  336. /// <summary>
  337. /// <para>Clamps value between 0 and 1 and returns value.</para>
  338. /// </summary>
  339. /// <param name="value"></param>
  340. public static float Clamp01(float value)
  341. {
  342. if ((double) value < 0.0)
  343. return 0.0f;
  344. if ((double) value > 1.0)
  345. return 1f;
  346. return value;
  347. }
  348. /// <summary>
  349. /// <para>Linearly interpolates between a and b by t.</para>
  350. /// </summary>
  351. /// <param name="a">The start value.</param>
  352. /// <param name="b">The end value.</param>
  353. /// <param name="t">The interpolation value between the two floats.</param>
  354. /// <returns>
  355. /// <para>The interpolated float result between the two float values.</para>
  356. /// </returns>
  357. public static float Lerp(float a, float b, float t)
  358. {
  359. return a + (b - a) * Mathf.Clamp01(t);
  360. }
  361. /// <summary>
  362. /// <para>Linearly interpolates between a and b by t with no limit to t.</para>
  363. /// </summary>
  364. /// <param name="a">The start value.</param>
  365. /// <param name="b">The end value.</param>
  366. /// <param name="t">The interpolation between the two floats.</param>
  367. /// <returns>
  368. /// <para>The float value as a result from the linear interpolation.</para>
  369. /// </returns>
  370. public static float LerpUnclamped(float a, float b, float t)
  371. {
  372. return a + (b - a) * t;
  373. }
  374. /// <summary>
  375. /// <para>Same as Lerp but makes sure the values interpolate correctly when they wrap around 360 degrees.</para>
  376. /// </summary>
  377. /// <param name="a"></param>
  378. /// <param name="b"></param>
  379. /// <param name="t"></param>
  380. public static float LerpAngle(float a, float b, float t)
  381. {
  382. float num = Mathf.Repeat(b - a, 360f);
  383. if ((double) num > 180.0)
  384. num -= 360f;
  385. return a + num * Mathf.Clamp01(t);
  386. }
  387. /// <summary>
  388. /// <para>Moves a value current towards target.</para>
  389. /// </summary>
  390. /// <param name="current">The current value.</param>
  391. /// <param name="target">The value to move towards.</param>
  392. /// <param name="maxDelta">The maximum change that should be applied to the value.</param>
  393. public static float MoveTowards(float current, float target, float maxDelta)
  394. {
  395. if ((double) Mathf.Abs(target - current) <= (double) maxDelta)
  396. return target;
  397. return current + Mathf.Sign(target - current) * maxDelta;
  398. }
  399. /// <summary>
  400. /// <para>Same as MoveTowards but makes sure the values interpolate correctly when they wrap around 360 degrees.</para>
  401. /// </summary>
  402. /// <param name="current"></param>
  403. /// <param name="target"></param>
  404. /// <param name="maxDelta"></param>
  405. public static float MoveTowardsAngle(float current, float target, float maxDelta)
  406. {
  407. float num = Mathf.DeltaAngle(current, target);
  408. if (-(double) maxDelta < (double) num && (double) num < (double) maxDelta)
  409. return target;
  410. target = current + num;
  411. return Mathf.MoveTowards(current, target, maxDelta);
  412. }
  413. /// <summary>
  414. /// <para>Interpolates between min and max with smoothing at the limits.</para>
  415. /// </summary>
  416. /// <param name="from"></param>
  417. /// <param name="to"></param>
  418. /// <param name="t"></param>
  419. public static float SmoothStep(float from, float to, float t)
  420. {
  421. t = Mathf.Clamp01(t);
  422. t = (float) (-2.0 * (double) t * (double) t * (double) t + 3.0 * (double) t * (double) t);
  423. return (float) ((double) to * (double) t + (double) from * (1.0 - (double) t));
  424. }
  425. public static float Gamma(float value, float absmax, float gamma)
  426. {
  427. bool flag = false;
  428. if ((double) value < 0.0)
  429. flag = true;
  430. float num1 = Mathf.Abs(value);
  431. if ((double) num1 > (double) absmax)
  432. return !flag? num1 : -num1;
  433. float num2 = Mathf.Pow(num1 / absmax, gamma) * absmax;
  434. return !flag? num2 : -num2;
  435. }
  436. /// <summary>
  437. /// <para>Loops the value t, so that it is never larger than length and never smaller than 0.</para>
  438. /// </summary>
  439. /// <param name="t"></param>
  440. /// <param name="length"></param>
  441. public static float Repeat(float t, float length)
  442. {
  443. return Mathf.Clamp(t - Mathf.Floor(t / length) * length, 0.0f, length);
  444. }
  445. /// <summary>
  446. /// <para>PingPongs the value t, so that it is never larger than length and never smaller than 0.</para>
  447. /// </summary>
  448. /// <param name="t"></param>
  449. /// <param name="length"></param>
  450. public static float PingPong(float t, float length)
  451. {
  452. t = Mathf.Repeat(t, length * 2f);
  453. return length - Mathf.Abs(t - length);
  454. }
  455. /// <summary>
  456. /// <para>Calculates the linear parameter t that produces the interpolant value within the range [a, b].</para>
  457. /// </summary>
  458. /// <param name="a"></param>
  459. /// <param name="b"></param>
  460. /// <param name="value"></param>
  461. public static float InverseLerp(float a, float b, float value)
  462. {
  463. if ((double) a != (double) b)
  464. return Mathf.Clamp01((float) (((double) value - (double) a) / ((double) b - (double) a)));
  465. return 0.0f;
  466. }
  467. /// <summary>
  468. /// <para>Calculates the shortest difference between two given angles given in degrees.</para>
  469. /// </summary>
  470. /// <param name="current"></param>
  471. /// <param name="target"></param>
  472. public static float DeltaAngle(float current, float target)
  473. {
  474. float num = Mathf.Repeat(target - current, 360f);
  475. if ((double) num > 180.0)
  476. num -= 360f;
  477. return num;
  478. }
  479. internal static bool LineIntersection(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, ref Vector2 result)
  480. {
  481. float num1 = p2.x - p1.x;
  482. float num2 = p2.y - p1.y;
  483. float num3 = p4.x - p3.x;
  484. float num4 = p4.y - p3.y;
  485. float num5 = (float) ((double) num1 * (double) num4 - (double) num2 * (double) num3);
  486. if ((double) num5 == 0.0)
  487. return false;
  488. float num6 = p3.x - p1.x;
  489. float num7 = p3.y - p1.y;
  490. float num8 = (float) ((double) num6 * (double) num4 - (double) num7 * (double) num3) / num5;
  491. result = new Vector2(p1.x + num8 * num1, p1.y + num8 * num2);
  492. return true;
  493. }
  494. internal static bool LineSegmentIntersection(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, ref Vector2 result)
  495. {
  496. float num1 = p2.x - p1.x;
  497. float num2 = p2.y - p1.y;
  498. float num3 = p4.x - p3.x;
  499. float num4 = p4.y - p3.y;
  500. float num5 = (float) ((double) num1 * (double) num4 - (double) num2 * (double) num3);
  501. if ((double) num5 == 0.0)
  502. return false;
  503. float num6 = p3.x - p1.x;
  504. float num7 = p3.y - p1.y;
  505. float num8 = (float) ((double) num6 * (double) num4 - (double) num7 * (double) num3) / num5;
  506. if ((double) num8 < 0.0 || (double) num8 > 1.0)
  507. return false;
  508. float num9 = (float) ((double) num6 * (double) num2 - (double) num7 * (double) num1) / num5;
  509. if ((double) num9 < 0.0 || (double) num9 > 1.0)
  510. return false;
  511. result = new Vector2(p1.x + num8 * num1, p1.y + num8 * num2);
  512. return true;
  513. }
  514. internal static long RandomToLong(System.Random r)
  515. {
  516. byte[] buffer = new byte[8];
  517. r.NextBytes(buffer);
  518. return (long) BitConverter.ToUInt64(buffer, 0) & long.MaxValue;
  519. }
  520. public static float Rad2Deg(float radians)
  521. {
  522. return (float)(radians * 180 / System.Math.PI);
  523. }
  524. public static float Deg2Rad(float degrees)
  525. {
  526. return (float)(degrees * System.Math.PI / 180);
  527. }
  528. public static Vector3 Rad2Deg(Vector3 radians)
  529. {
  530. return new Vector3(
  531. (float)(radians.x * 180 / System.Math.PI),
  532. (float)(radians.y * 180 / System.Math.PI),
  533. (float)(radians.z * 180 / System.Math.PI));
  534. }
  535. public static Vector3 Deg2Rad(Vector3 degrees)
  536. {
  537. return new Vector3(
  538. (float)(degrees.x * System.Math.PI / 180),
  539. (float)(degrees.y * System.Math.PI / 180),
  540. (float)(degrees.z * System.Math.PI / 180));
  541. }
  542. public const float CosAngle20 = 0.9396926208f;
  543. public const float CompareEpsilon = 0.000001f;
  544. public static bool CompareApproximate(float f0, float f1, float epsilon = CompareEpsilon)
  545. {
  546. return System.Math.Abs(f0 - f1) < epsilon;
  547. }
  548. public static bool CompareApproximate(double f0, double f1, float epsilon = CompareEpsilon)
  549. {
  550. return System.Math.Abs(f0 - f1) < epsilon;
  551. }
  552. }
  553. }