Advertisement
p1ayer

System.Math.h

Oct 8th, 2014
371
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.38 KB | None | 0 0
  1. /*
  2.  * System.Math.h
  3.  *
  4.  * Code Status: Drafts
  5.  *  Created on: Taiwan
  6.  *      Author: player
  7.  */
  8.  
  9. #ifndef SYSTEM_MATH_H_
  10. #define SYSTEM_MATH_H_
  11.  
  12. #if _MSC_VER > 1000
  13. #pragma once
  14. #endif
  15.  
  16. #include <algorithm>
  17. #include <cmath>
  18. #include <vector>
  19.  
  20. namespace System {
  21.     /*
  22.     <summary>
  23.     Provides constants and static methods for trigonometric, logarithmic, and other common mathematical functions.
  24.     提供常數和靜態方法,三角函數,對數和其他常見的數學函數。
  25.     </summary>
  26.     */
  27.     namespace Math {
  28.         /*
  29.         <summary>
  30.         Provides constants
  31.         提供常數
  32.         </summary>
  33.         */
  34.         namespace Constants {
  35.             //常數的數值精度
  36.             typedef float ConstantType;
  37.             //typedef double ConstantType;
  38.             //typedef long double ConstantType;
  39.  
  40.             ///<summary>常數 E</summary>
  41.             const ConstantType _E = std::exp(static_cast<ConstantType>(1));
  42.  
  43.             //<summary>常數 log2(e)</summary>
  44.             const ConstantType _LOG2E = std::log2(static_cast<ConstantType>(_E));
  45.  
  46.             //<summary>常數 log10(e)</summary>
  47.             const ConstantType _LOG10E = std::log10(static_cast<ConstantType>(_E));
  48.  
  49.             //<summary>常數 ln(2)</summary>
  50.             const ConstantType _LN2 = std::log(static_cast<ConstantType>(2));
  51.  
  52.             //<summary>常數 ln(10)</summary>
  53.             const ConstantType _LN10 = std::log(static_cast<ConstantType>(10));
  54.  
  55.             //<summary>常數 PI</summary>
  56.             const ConstantType _PI = std::atan(static_cast<ConstantType>(1)) * static_cast<ConstantType>(4);
  57.  
  58.             //<summary>常數 1/PI</summary>
  59.             const ConstantType _1DIVPI = static_cast<ConstantType>(1) / _PI;
  60.  
  61.             //<summary>常數 2*PI</summary>
  62.             const ConstantType _2PI = static_cast<ConstantType>(2) * _PI;
  63.  
  64.             //<summary>常數 1/(2*PI)</summary>
  65.             const ConstantType _1DIV2PI = static_cast<ConstantType>(1) / _2PI;
  66.  
  67.             //<summary>常數 PI/2</summary>
  68.             const ConstantType _PIDIV2 = _PI / static_cast<ConstantType>(2);
  69.  
  70.             //<summary>常數 2/PI</summary>
  71.             const ConstantType _2DIVPI = static_cast<ConstantType>(2) / _PI;
  72.  
  73.             //<summary>常數 PI/4</summary>
  74.             const ConstantType _PIDIV4 = _PI / static_cast<ConstantType>(4);
  75.  
  76.             //<summary>常數 4/PI</summary>
  77.             const ConstantType _4DIVPI = static_cast<ConstantType>(4) / _PI;
  78.  
  79.             //<summary>常數 PI/180</summary>
  80.             const ConstantType _PIDIV180 = _PI / static_cast<ConstantType>(180);
  81.  
  82.             //<summary>常數 180/PI</summary>
  83.             const ConstantType _180DIVPI = static_cast<ConstantType>(180) / _PI;
  84.  
  85.             //<summary>常數 2/sqrt(pi)</summary>
  86.             const ConstantType _2DIVSQRTPI = static_cast<ConstantType>(2) / std::sqrt(_PI);
  87.  
  88.             //<summary>常數 sqrt(2)</summary>
  89.             const ConstantType _SQRT2 = std::sqrt(static_cast<ConstantType>(2));
  90.  
  91.             //<summary>常數 1/sqrt(2)</summary>
  92.             const ConstantType _1DIVSQRT2 = static_cast<ConstantType>(1) / std::sqrt(static_cast<ConstantType>(2));
  93.         } /* namespace Constants */
  94.  
  95.         //-----------------------------------------------
  96.         //角度轉換
  97.         template <typename T> inline T ToRadian(T degree) {
  98.             return degree * Constants::_PIDIV180;
  99.         }
  100.  
  101.         template <typename T> inline T ToDegree(T radian) {
  102.             return radian * Constants::_180DIVPI;
  103.         }
  104.         //-----------------------------------------------
  105.  
  106.         //<summary>絕對值</summary>
  107.         template <typename T> inline T Abs(T x) {
  108.             return (x >= static_cast<T>(0)) ? x : -x;
  109.         }
  110.  
  111.         //<summary>距離</summary>
  112.         template <typename T> inline T Distance(T value1, T value2) {
  113.             return Math::Abs(value1 - value2);
  114.         }
  115.  
  116.         //<summary>夾鉗 ( min < value < max )</summary>
  117.         template <typename T> inline T Clamp(T value, T min, T max) {
  118.             return Min(Max(min, value), max);
  119.         }
  120.  
  121.         //<summary>大於或等於 x 的最小整數值</summary>
  122.         template <typename T> inline T Ceiling(T x) {
  123.             return std::ceil(x);
  124.         }
  125.  
  126.         //<summary>階乘 (n!)</summary>
  127.         template <typename T> T Factorial(T n) {
  128.             T ret = n;
  129.             for (T x = n-1; x > 1; x--)
  130.                 ret *= x;
  131.        
  132.             return ret;
  133.         }
  134.  
  135.         //<summary>排列 Permutation (在n個之中隨機取出k個, 有幾種)</summary>
  136.         template <typename T> T Permutation(T n, T k) {
  137.             T ret = 1;
  138.             for (T x = n; x >= k; x--)
  139.                 ret *= x;
  140.             return ret;
  141.         }
  142.  
  143.         //<summary>組合 Combination (在n個之中隨機取出k個, 組合有幾種)</summary>
  144.         template <typename T> T Combination(T n, T k) {
  145.             T ret = 1;
  146.             for (T x = n; x >= k; x--)
  147.                 ret *= x;
  148.  
  149.             return (ret / Factorial(k));
  150.         }
  151.  
  152.         //<summary>小於或等於 x 的最小整數值</summary>
  153.         template <typename T> inline T Floor(T x) {
  154.             return std::floor(x);
  155.         }
  156.  
  157.         //-----------------------------------------------
  158.         // 2個傳入參數
  159.  
  160.         //<summary>算術平均數</summary>
  161.         template <typename T> inline T Average(T x, T y) {
  162.             return (x + y) / static_cast<T>(2);
  163.         }
  164.  
  165.         //<summary>最小值</summary>
  166.         template <typename T> inline T Min(T x, T y) {
  167.             return (x <= y) ? x : y;
  168.         }
  169.  
  170.         //<summary>最大值</summary>
  171.         template <typename T> inline T Max(T x, T y) {
  172.             return (x >= y) ? x : y;
  173.         }
  174.  
  175.         //<summary>加總</summary>
  176.         template <typename T> inline T Sum(T x, T y) {
  177.             return (x + y);
  178.         }
  179.  
  180.         //<summary>線性內插值</summary>
  181.         template <typename T> inline T Lerp(T value1, T value2, T amount) {
  182.             return value1 + (value2 - value1) * amount;
  183.         }
  184.  
  185.         //-----------------------------------------------
  186.         // 多個傳入參數 (動態傳入參數)
  187.  
  188.         //<summary>算術平均數</summary>
  189.         //<remarks>若傳入浮點數, 限定使用double; 因為浮點數在推入堆疊時, 若無明確宣告資料型別, 會當成double來存放</remarks>
  190.         template <typename T> T Average(int count, T arg1, T arg2, ...) {
  191.             va_list valist;
  192.             T sum = 0;
  193.  
  194.             /* initialize valist for num number of arguments */
  195.             va_start(valist, count);
  196.  
  197.             /* access all the arguments assigned to valist */
  198.             for (int i = 0; i < count; i++)
  199.                 sum += va_arg(valist, T);
  200.  
  201.             /* clean memory reserved for valist */
  202.             va_end(valist);
  203.  
  204.             return sum / count;
  205.         }
  206.  
  207.         //<summary>最小值</summary>
  208.         //<remarks>若傳入浮點數, 限定使用double; 因為浮點數在推入堆疊時, 若無明確宣告資料型別, 會當成double來存放</remarks>
  209.         template <typename T> T Min(int count, T arg1, T arg2, ...) {
  210.             va_list valist;
  211.  
  212.             /* initialize valist for num number of arguments */
  213.             va_start(valist, count);
  214.             T ret = va_arg(valist, T);
  215.             T x;
  216.  
  217.             /* access all the arguments assigned to valist */
  218.             for (int i = 1; i < count; i++) {
  219.                 x = va_arg(valist, T);
  220.                 if (ret > x)
  221.                     ret = x;
  222.             }
  223.  
  224.             /* clean memory reserved for valist */
  225.             va_end(valist);
  226.  
  227.             return ret;
  228.         }
  229.  
  230.         //<summary>最大值</summary>
  231.         //<remarks>若傳入浮點數, 限定使用double; 因為浮點數在推入堆疊時, 若無明確宣告資料型別, 會當成double來存放</remarks>
  232.         template <typename T> T Max(int count, T arg1, T arg2, ...) {
  233.             va_list valist;
  234.  
  235.             /* initialize valist for num number of arguments */
  236.             va_start(valist, count);
  237.             T ret = va_arg(valist, T);
  238.             T x;
  239.  
  240.             /* access all the arguments assigned to valist */
  241.             for (int i = 1 ; i < count; i++) {
  242.                 x = va_arg(valist, T);
  243.                 if (ret < x)
  244.                     ret = x;
  245.             }
  246.  
  247.             /* clean memory reserved for valist */
  248.             va_end(valist);
  249.  
  250.             return ret;
  251.         }
  252.  
  253.         //<summary>加總</summary>
  254.         //<remarks>若傳入浮點數, 限定使用double; 因為浮點數在推入堆疊時, 若無明確宣告資料型別, 會當成double來存放</remarks>
  255.         template <typename T> T Sum(int count, T arg1, T arg2, ...) {
  256.             va_list valist;
  257.             T sum = T(0);
  258.  
  259.             /* initialize valist for num number of arguments */
  260.             va_start(valist, count);
  261.  
  262.             /* access all the arguments assigned to valist */
  263.             for (int i = 0; i < count; i++)
  264.                 sum += va_arg(valist, T);
  265.  
  266.             /* clean memory reserved for valist */
  267.             va_end(valist);
  268.  
  269.             return sum;
  270.         }
  271.  
  272.         //-----------------------------------------------
  273.         // 多個傳入參數 (配合STL使用)
  274.         //<summary>算術平均數</summary>
  275.         template<typename T, typename I = std::vector<T>::iterator>
  276.         inline T Average(I _F, I _L) {
  277.             T total = static_cast<T>(0);
  278.             T count = static_cast<T>(0);
  279.             for (; _F != _L; ++_F, ++count)
  280.                 total += *_F;
  281.             return (total / count);
  282.         }
  283.  
  284.         //<summary>最小值</summary>
  285.         template<typename T, typename I = std::vector<T>::iterator>
  286.         inline T Min(I _F, I _L) {
  287.             T ret = *_F;
  288.             _F++;
  289.             for (; _F != _L; ++_F)
  290.                 if (ret > *_F)
  291.                     ret = *_F;
  292.             return ret;
  293.         }
  294.  
  295.         //<summary>最大值</summary>
  296.         template<typename T, typename I = std::vector<T>::iterator>
  297.         inline T Max(I _F, I _L) {
  298.             T ret = *_F;
  299.             _F++;
  300.             for (; _F != _L; ++_F)
  301.                 if (ret < *_F)
  302.                     ret = *_F;
  303.             return ret;
  304.         }
  305.  
  306.         //<summary>加總</summary>
  307.         template<typename T, typename I = std::vector<T>::iterator>
  308.         inline T Sum(I _F, I _L) {
  309.             T ret = static_cast<T>(0);
  310.             for (; _F != _L; ++_F)
  311.                 ret += *_F;
  312.             return ret;
  313.         }
  314.  
  315.         //-----------------------------------------------
  316.  
  317.         template <typename T> inline T Exp(T num) {
  318.             return std::exp(num);
  319.         }
  320.  
  321.         template <typename T> inline T Log(T num) {
  322.             return std::log(num);
  323.         }
  324.  
  325.         template <typename T> inline T Log10(T num) {
  326.             return std::log10(num);
  327.         }
  328.  
  329.         //<summary>指數</summary>
  330.         template <typename T> inline T Pow(T base, T expx) {
  331.             return std::pow(base, expx);
  332.         }
  333.  
  334.         //<summary>正負號</summary>
  335.         template <typename T> inline int Sign(T x) {
  336.             if (x < static_cast<T>(0))
  337.                 return -1;
  338.             if (x > static_cast<T>(0))
  339.                 return 1;
  340.             return 0;
  341.         }
  342.  
  343.         //<summary>平方根 (Square root)</summary>
  344.         template <typename T> inline T Sqrt(T x) {
  345.             return std::sqrt(x);
  346.         }
  347.  
  348.         //-----------------------------------------------
  349.         //三角函數
  350.  
  351.         //<summary>三角函數Sine</summary>
  352.         template <typename T> inline T Sin(T x) {
  353.             return std::sin(x);
  354.         }
  355.  
  356.         //<summary>三角函數Cosine</summary>
  357.         template <typename T> inline T Cos(T x) {
  358.             return std::cos(x);
  359.         }
  360.  
  361.         //<summary>三角函數Tangent</summary>
  362.         template <typename T> inline T Tan(T x) {
  363.             return std::tan(x);
  364.         }
  365.  
  366.         //<summary>三角函數Cotangent</summary>
  367.         template <typename T> inline T Cot(T x) {
  368.             return static_cast<T>(1) / std::tan(x);
  369.         }
  370.  
  371.         //<summary>三角函數Secant</summary>
  372.         template <typename T> inline T Sec(T x) {
  373.             return static_cast<T>(1) / std::cos(x);
  374.         }
  375.  
  376.         //<summary>三角函數Cosecant</summary>
  377.         template <typename T> inline T Csc(T x) {
  378.             return static_cast<T>(1) / std::sin(x);
  379.         }
  380.  
  381.         //-----------------------------------------------
  382.         //反三角函數
  383.  
  384.         //<summary>反三角函數Arcsine</summary>
  385.         template <typename T> inline T ArcSin(T x) {
  386.             return std::asin(x);
  387.         }
  388.  
  389.         //<summary>反三角函數Arccosine</summary>
  390.         template <typename T> inline T ArcCos(T x) {
  391.             return std::acos(x);
  392.         }
  393.  
  394.         //<summary>反三角函數Arctangent</summary>
  395.         template <typename T> inline T ArcTan(T x) {
  396.             return std::atan(x);
  397.         }
  398.  
  399.         //<summary>反三角函數Arccotangent</summary>
  400.         template <typename T> inline T ArcCot(T x) {
  401.             return Constant::_PIDIV2 - std::atan(x);
  402.         }
  403.  
  404.         //<summary>反三角函數Arcsecant</summary>
  405.         template <typename T> inline T ArcSec(T x) {
  406.             return std::acos(static_cast<T>(1) / x);
  407.         }
  408.  
  409.         //<summary>反三角函數Arccosecant</summary>
  410.         template <typename T> inline T ArcCsc(T x) {
  411.             return std::asin(static_cast<T>(1) / x);
  412.         }
  413.  
  414.         //-----------------------------------------------
  415.         //雙曲函數
  416.  
  417.         //<summary>雙曲函數Hyperbolic Sine</summary>
  418.         template <typename T>
  419.         inline T Sinh(T x) {
  420.             return std::sinh(x);
  421.         }
  422.  
  423.         //<summary>雙曲函數Hyperbolic Cosine</summary>
  424.         template <typename T> inline T Cosh(T x) {
  425.             return std::cosh(x);
  426.         }
  427.  
  428.         //<summary>雙曲函數Hyperbolic Tangent</summary>
  429.         template <typename T> inline T Tanh(T x) {
  430.             return std::tanh(x);
  431.         }
  432.  
  433.         //<summary>雙曲函數Hyperbolic Cotangent</summary>
  434.         template <typename T> inline T Coth(T x) {
  435.             return static_cast<T>(1) / std::tanh(x);
  436.         }
  437.  
  438.         //<summary>雙曲函數Hyperbolic Secant</summary>
  439.         template <typename T> inline T Sech(T x) {
  440.             return static_cast<T>(1) / std::cosh(x);
  441.         }
  442.  
  443.         //<summary>雙曲函數Hyperbolic Cosecant</summary>
  444.         template <typename T> inline T Csch(T x) {
  445.             return static_cast<T>(1) / std::sinh(x);
  446.         }
  447.  
  448.         //-----------------------------------------------
  449.         //反雙曲函數
  450.         template <typename T> inline T ArcSinh(T x) {
  451.             return Log(x + Sqrt(x*x + static_cast<T>(1)));
  452.         }
  453.  
  454.         template <typename T> inline T ArcCosh(T x) {
  455.             return Log(x + Sqrt(x*x - static_cast<T>(1)));
  456.         }
  457.  
  458.         template <typename T> inline T ArcTanh(T x) {
  459.             return Log((x + static_cast<T>(1)) / (-x + static_cast<T>(1))) / static_cast<T>(2);
  460.         }
  461.  
  462.         template <typename T> inline T ArcCoth(T x) {
  463.             return Log((x + static_cast<T>(1)) / (x - static_cast<T>(1))) / static_cast<T>(2);
  464.         }
  465.  
  466.         template <typename T> inline T ArcSech(T x) {
  467.             T t = Sqrt(-x*x + static_cast<T>(1));
  468.             return Log((t + static_cast<T>(1)) / (-t + static_cast<T>(1))) / static_cast<T>(2);
  469.         }
  470.  
  471.         template <typename T> inline T ArcCsch(T x) {
  472.             T t = Sqrt(-x*x + static_cast<T>(1));
  473.             if (x < 0)
  474.                 return Log((-t + static_cast<T>(1)) / x);
  475.             if (x > 0)
  476.                 return Log((t + static_cast<T>(1)) / x);
  477.         }
  478.  
  479.         //-----------------------------------------------
  480.         //其他
  481.  
  482.         template <typename T> inline T Barycentric(T value1, T value2, T value3, T amount1, T amount2) {
  483.             return value1 + amount1 * (value2 - value1) + amount2 * (value3 - value1);
  484.         }
  485.  
  486.         template <typename T> inline T CatmullRom(T value1, T value2, T value3, T value4, T amount) {
  487.             T num = amount * amount;
  488.             T num2 = amount * num;
  489.             return 0.5f * (2.0f * value2 + (-value1 + value3) * amount
  490.                 + (2.0f * value1 - 5.0f * value2 + 4.0f * value3 - value4) * num
  491.                 + (-value1 + 3.0f * value2 - 3.0f * value3 + value4) * num2);
  492.         }
  493.  
  494.         template <typename T> inline T Hermite(T value1, T tangent1, T value2, T tangent2, T amount)
  495.         {
  496.             T num = amount * amount;
  497.             T num2 = amount * num;
  498.             T num3 = 2.0f * num2 - 3.0f * num + 1.0f;
  499.             T num4 = -2.0f * num2 + 3.0f * num;
  500.             T num5 = num2 - 2.0f * num + amount;
  501.             T num6 = num2 - num;
  502.             return value1 * num3 + value2 * num4 + tangent1 * num5 + tangent2 * num6;
  503.         }      
  504.  
  505.         template <typename T> inline T SmoothStep(T value1, T value2, T amount) {
  506.             T num = Math::Clamp(amount, 0.0f, 1.0f);
  507.             return Math::Lerp(value1, value2, num * num * (3.0f - 2.0f * num));
  508.         }
  509.     } /* namespace Math */
  510. } /* namespace System */
  511.  
  512. #endif /* SYSTEM_MATH_H_ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement