MathHelper.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. #region --- License ---
  2. /* Licensed under the MIT/X11 license.
  3. * Copyright (c) 2006-2008 the OpenTK Team.
  4. * This notice may not be removed from any source distribution.
  5. * See license.txt for licensing detailed licensing details.
  6. *
  7. * Contributions by Andy Gill, James Talton and Georg Wächter.
  8. */
  9. /*
  10. Copyright (c) 2014, Lars Brubaker
  11. All rights reserved.
  12. Redistribution and use in source and binary forms, with or without
  13. modification, are permitted provided that the following conditions are met:
  14. 1. Redistributions of source code must retain the above copyright notice, this
  15. list of conditions and the following disclaimer.
  16. 2. Redistributions in binary form must reproduce the above copyright notice,
  17. this list of conditions and the following disclaimer in the documentation
  18. and/or other materials provided with the distribution.
  19. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  23. ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  26. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. The views and conclusions contained in the software and documentation are those
  30. of the authors and should not be interpreted as representing official policies,
  31. either expressed or implied, of the FreeBSD Project.
  32. */
  33. #endregion --- License ---
  34. using System;
  35. namespace MatterHackers.VectorMath
  36. {
  37. /// <summary>
  38. /// Contains common mathematical functions and constants.
  39. /// </summary>
  40. public static class MathHelper
  41. {
  42. #region Fields
  43. /// <summary>
  44. /// Defines the value of Pi as a <see cref="System.Single"/>.
  45. /// </summary>
  46. public const double Pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930382f;
  47. public const double Tau = Pi * 2;
  48. /// <summary>
  49. /// Defines the value of Pi divided by two as a <see cref="System.Single"/>.
  50. /// </summary>
  51. public const double PiOver2 = Pi / 2;
  52. /// <summary>
  53. /// Defines the value of Pi divided by three as a <see cref="System.Single"/>.
  54. /// </summary>
  55. public const double PiOver3 = Pi / 3;
  56. /// <summary>
  57. /// Defines the value of Pi divided by four as a <see cref="System.Single"/>.
  58. /// </summary>
  59. public const double PiOver4 = Pi / 4;
  60. /// <summary>
  61. /// Defines the value of Pi divided by six as a <see cref="System.Single"/>.
  62. /// </summary>
  63. public const double PiOver6 = Pi / 6;
  64. /// <summary>
  65. /// Defines the value of Pi multiplied by two as a <see cref="System.Single"/>.
  66. /// </summary>
  67. public const double TwoPi = 2 * Pi;
  68. /// <summary>
  69. /// Defines the value of Pi multiplied by 3 and divided by two as a <see cref="System.Single"/>.
  70. /// </summary>
  71. public const double ThreePiOver2 = 3 * Pi / 2;
  72. /// <summary>
  73. /// Defines the value of E as a <see cref="System.Single"/>.
  74. /// </summary>
  75. public const double E = 2.71828182845904523536f;
  76. /// <summary>
  77. /// Defines the base-10 logarithm of E.
  78. /// </summary>
  79. public const double Log10E = 0.434294482f;
  80. /// <summary>
  81. /// Defines the base-2 logarithm of E.
  82. /// </summary>
  83. public const double Log2E = 1.442695041f;
  84. #endregion Fields
  85. #region Public Members
  86. public static int FirstPowerTowGreaterThanOrEqualTo(int n)
  87. {
  88. int pow2Size = 1;
  89. while (pow2Size < n)
  90. {
  91. pow2Size <<= 1;
  92. }
  93. return pow2Size;
  94. }
  95. #region NextPowerOfTwo
  96. /// <summary>
  97. /// Returns the next power of two that is larger than the specified number.
  98. /// </summary>
  99. /// <param name="n">The specified number.</param>
  100. /// <returns>The next power of two.</returns>
  101. public static long NextPowerOfTwo(long n)
  102. {
  103. if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
  104. return (long)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
  105. }
  106. /// <summary>
  107. /// Returns the next power of two that is larger than the specified number.
  108. /// </summary>
  109. /// <param name="n">The specified number.</param>
  110. /// <returns>The next power of two.</returns>
  111. public static int NextPowerOfTwo(int n)
  112. {
  113. if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
  114. return (int)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
  115. }
  116. public static double Clamp(double test, double min, double max)
  117. {
  118. if(test < min)
  119. {
  120. return min;
  121. }
  122. if(test > max)
  123. {
  124. return max;
  125. }
  126. return test;
  127. }
  128. /// <summary>
  129. /// Returns the next power of two that is larger than the specified number.
  130. /// </summary>
  131. /// <param name="n">The specified number.</param>
  132. /// <returns>The next power of two.</returns>
  133. public static float NextPowerOfTwo(float n)
  134. {
  135. if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
  136. return (float)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
  137. }
  138. /// <summary>
  139. /// Returns the next power of two that is larger than the specified number.
  140. /// </summary>
  141. /// <param name="n">The specified number.</param>
  142. /// <returns>The next power of two.</returns>
  143. public static double NextPowerOfTwo(double n)
  144. {
  145. if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
  146. return System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
  147. }
  148. #endregion NextPowerOfTwo
  149. #region Factorial
  150. /// <summary>Calculates the factorial of a given natural number.
  151. /// </summary>
  152. /// <param name="n">The number.</param>
  153. /// <returns>n!</returns>
  154. public static long Factorial(int n)
  155. {
  156. long result = 1;
  157. for (; n > 1; n--)
  158. result *= n;
  159. return result;
  160. }
  161. #endregion Factorial
  162. #region BinomialCoefficient
  163. /// <summary>
  164. /// Calculates the binomial coefficient <paramref name="n"/> above <paramref name="k"/>.
  165. /// </summary>
  166. /// <param name="n">The n.</param>
  167. /// <param name="k">The k.</param>
  168. /// <returns>n! / (k! * (n - k)!)</returns>
  169. public static long BinomialCoefficient(int n, int k)
  170. {
  171. return Factorial(n) / (Factorial(k) * Factorial(n - k));
  172. }
  173. #endregion BinomialCoefficient
  174. static public double Range0ToTau(double Value)
  175. {
  176. if (Value < 0)
  177. {
  178. Value += Tau;
  179. }
  180. if ((Value - Tau) > .00001)
  181. {
  182. int numTurns = (int)(Value / Tau);
  183. Value -= (Tau * numTurns);
  184. }
  185. if (Value < 0 || Value > Tau) throw new Exception("Value >= 0 && Value <= Tau");
  186. return Value;
  187. }
  188. static public double GetDeltaAngle(double StartAngle, double EndAngle)
  189. {
  190. if (StartAngle != Range0ToTau(StartAngle)) throw new Exception("StartAngle != Range0ToTau(StartAngle)");
  191. if (EndAngle != Range0ToTau(EndAngle)) throw new Exception("EndAngle != Range0ToTau(EndAngle)");
  192. double DeltaAngle = EndAngle - StartAngle;
  193. if (DeltaAngle > Tau)
  194. {
  195. DeltaAngle -= Tau;
  196. }
  197. if (DeltaAngle < -Tau)
  198. {
  199. DeltaAngle += Tau;
  200. }
  201. return DeltaAngle;
  202. }
  203. #region Conversions
  204. #region Angles
  205. /// <summary>
  206. /// Convert degrees to radians
  207. /// </summary>
  208. /// <param name="degrees">An angle in degrees</param>
  209. /// <returns>The angle expressed in radians</returns>
  210. public static double DegreesToRadians(double degrees)
  211. {
  212. const double degToRad = System.Math.PI / 180.0f;
  213. return degrees * degToRad;
  214. }
  215. /// <summary>
  216. /// Convert radians to degrees
  217. /// </summary>
  218. /// <param name="radians">An angle in radians</param>
  219. /// <returns>The angle expressed in degrees</returns>
  220. public static double RadiansToDegrees(double radians)
  221. {
  222. const double radToDeg = 180.0f / System.Math.PI;
  223. return radians * radToDeg;
  224. }
  225. #endregion Angles
  226. #region Lengths
  227. public static double InchesToMm(double inches)
  228. {
  229. return inches * 25.4;
  230. }
  231. #endregion Lengths
  232. #endregion Conversions
  233. #region Swap
  234. /// <summary>
  235. /// Swaps two double values.
  236. /// </summary>
  237. /// <param name="a">The first value.</param>
  238. /// <param name="b">The second value.</param>
  239. public static void Swap(ref double a, ref double b)
  240. {
  241. double temp = a;
  242. a = b;
  243. b = temp;
  244. }
  245. /// <summary>
  246. /// Swaps two float values.
  247. /// </summary>
  248. /// <param name="a">The first value.</param>
  249. /// <param name="b">The second value.</param>
  250. public static void Swap(ref float a, ref float b)
  251. {
  252. float temp = a;
  253. a = b;
  254. b = temp;
  255. }
  256. #endregion Swap
  257. #endregion Public Members
  258. #region Static Functions
  259. public static bool AlmostEqual(double a, double b, double differenceAllowed)
  260. {
  261. if (a > b - differenceAllowed && a < b + differenceAllowed)
  262. {
  263. return true;
  264. }
  265. return false;
  266. }
  267. #endregion Static Functions
  268. }
  269. }