123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- #region --- License ---
- /* Licensed under the MIT/X11 license.
- * Copyright (c) 2006-2008 the OpenTK Team.
- * This notice may not be removed from any source distribution.
- * See license.txt for licensing detailed licensing details.
- *
- * Contributions by Andy Gill, James Talton and Georg Wächter.
- */
- /*
- Copyright (c) 2014, Lars Brubaker
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- 1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- 2. 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.
- 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.
- The views and conclusions contained in the software and documentation are those
- of the authors and should not be interpreted as representing official policies,
- either expressed or implied, of the FreeBSD Project.
- */
- #endregion --- License ---
- using System;
- namespace MatterHackers.VectorMath
- {
- /// <summary>
- /// Contains common mathematical functions and constants.
- /// </summary>
- public static class MathHelper
- {
- #region Fields
- /// <summary>
- /// Defines the value of Pi as a <see cref="System.Single"/>.
- /// </summary>
- public const double Pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930382f;
- public const double Tau = Pi * 2;
- /// <summary>
- /// Defines the value of Pi divided by two as a <see cref="System.Single"/>.
- /// </summary>
- public const double PiOver2 = Pi / 2;
- /// <summary>
- /// Defines the value of Pi divided by three as a <see cref="System.Single"/>.
- /// </summary>
- public const double PiOver3 = Pi / 3;
- /// <summary>
- /// Defines the value of Pi divided by four as a <see cref="System.Single"/>.
- /// </summary>
- public const double PiOver4 = Pi / 4;
- /// <summary>
- /// Defines the value of Pi divided by six as a <see cref="System.Single"/>.
- /// </summary>
- public const double PiOver6 = Pi / 6;
- /// <summary>
- /// Defines the value of Pi multiplied by two as a <see cref="System.Single"/>.
- /// </summary>
- public const double TwoPi = 2 * Pi;
- /// <summary>
- /// Defines the value of Pi multiplied by 3 and divided by two as a <see cref="System.Single"/>.
- /// </summary>
- public const double ThreePiOver2 = 3 * Pi / 2;
- /// <summary>
- /// Defines the value of E as a <see cref="System.Single"/>.
- /// </summary>
- public const double E = 2.71828182845904523536f;
- /// <summary>
- /// Defines the base-10 logarithm of E.
- /// </summary>
- public const double Log10E = 0.434294482f;
- /// <summary>
- /// Defines the base-2 logarithm of E.
- /// </summary>
- public const double Log2E = 1.442695041f;
- #endregion Fields
- #region Public Members
- public static int FirstPowerTowGreaterThanOrEqualTo(int n)
- {
- int pow2Size = 1;
- while (pow2Size < n)
- {
- pow2Size <<= 1;
- }
- return pow2Size;
- }
- #region NextPowerOfTwo
- /// <summary>
- /// Returns the next power of two that is larger than the specified number.
- /// </summary>
- /// <param name="n">The specified number.</param>
- /// <returns>The next power of two.</returns>
- public static long NextPowerOfTwo(long n)
- {
- if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
- return (long)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
- }
- /// <summary>
- /// Returns the next power of two that is larger than the specified number.
- /// </summary>
- /// <param name="n">The specified number.</param>
- /// <returns>The next power of two.</returns>
- public static int NextPowerOfTwo(int n)
- {
- if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
- return (int)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
- }
- public static double Clamp(double test, double min, double max)
- {
- if(test < min)
- {
- return min;
- }
- if(test > max)
- {
- return max;
- }
- return test;
- }
- /// <summary>
- /// Returns the next power of two that is larger than the specified number.
- /// </summary>
- /// <param name="n">The specified number.</param>
- /// <returns>The next power of two.</returns>
- public static float NextPowerOfTwo(float n)
- {
- if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
- return (float)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
- }
- /// <summary>
- /// Returns the next power of two that is larger than the specified number.
- /// </summary>
- /// <param name="n">The specified number.</param>
- /// <returns>The next power of two.</returns>
- public static double NextPowerOfTwo(double n)
- {
- if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
- return System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
- }
- #endregion NextPowerOfTwo
- #region Factorial
- /// <summary>Calculates the factorial of a given natural number.
- /// </summary>
- /// <param name="n">The number.</param>
- /// <returns>n!</returns>
- public static long Factorial(int n)
- {
- long result = 1;
- for (; n > 1; n--)
- result *= n;
- return result;
- }
- #endregion Factorial
- #region BinomialCoefficient
- /// <summary>
- /// Calculates the binomial coefficient <paramref name="n"/> above <paramref name="k"/>.
- /// </summary>
- /// <param name="n">The n.</param>
- /// <param name="k">The k.</param>
- /// <returns>n! / (k! * (n - k)!)</returns>
- public static long BinomialCoefficient(int n, int k)
- {
- return Factorial(n) / (Factorial(k) * Factorial(n - k));
- }
- #endregion BinomialCoefficient
- static public double Range0ToTau(double Value)
- {
- if (Value < 0)
- {
- Value += Tau;
- }
- if ((Value - Tau) > .00001)
- {
- int numTurns = (int)(Value / Tau);
- Value -= (Tau * numTurns);
- }
- if (Value < 0 || Value > Tau) throw new Exception("Value >= 0 && Value <= Tau");
- return Value;
- }
- static public double GetDeltaAngle(double StartAngle, double EndAngle)
- {
- if (StartAngle != Range0ToTau(StartAngle)) throw new Exception("StartAngle != Range0ToTau(StartAngle)");
- if (EndAngle != Range0ToTau(EndAngle)) throw new Exception("EndAngle != Range0ToTau(EndAngle)");
- double DeltaAngle = EndAngle - StartAngle;
- if (DeltaAngle > Tau)
- {
- DeltaAngle -= Tau;
- }
- if (DeltaAngle < -Tau)
- {
- DeltaAngle += Tau;
- }
- return DeltaAngle;
- }
- #region Conversions
- #region Angles
- /// <summary>
- /// Convert degrees to radians
- /// </summary>
- /// <param name="degrees">An angle in degrees</param>
- /// <returns>The angle expressed in radians</returns>
- public static double DegreesToRadians(double degrees)
- {
- const double degToRad = System.Math.PI / 180.0f;
- return degrees * degToRad;
- }
- /// <summary>
- /// Convert radians to degrees
- /// </summary>
- /// <param name="radians">An angle in radians</param>
- /// <returns>The angle expressed in degrees</returns>
- public static double RadiansToDegrees(double radians)
- {
- const double radToDeg = 180.0f / System.Math.PI;
- return radians * radToDeg;
- }
- #endregion Angles
- #region Lengths
- public static double InchesToMm(double inches)
- {
- return inches * 25.4;
- }
- #endregion Lengths
- #endregion Conversions
- #region Swap
- /// <summary>
- /// Swaps two double values.
- /// </summary>
- /// <param name="a">The first value.</param>
- /// <param name="b">The second value.</param>
- public static void Swap(ref double a, ref double b)
- {
- double temp = a;
- a = b;
- b = temp;
- }
- /// <summary>
- /// Swaps two float values.
- /// </summary>
- /// <param name="a">The first value.</param>
- /// <param name="b">The second value.</param>
- public static void Swap(ref float a, ref float b)
- {
- float temp = a;
- a = b;
- b = temp;
- }
- #endregion Swap
- #endregion Public Members
- #region Static Functions
- public static bool AlmostEqual(double a, double b, double differenceAllowed)
- {
- if (a > b - differenceAllowed && a < b + differenceAllowed)
- {
- return true;
- }
- return false;
- }
- #endregion Static Functions
- }
- }
|