| 1 | /// @ref gtx_fast_trigonometry |
| 2 | |
| 3 | namespace glm{ |
| 4 | namespace detail |
| 5 | { |
| 6 | template<length_t L, typename T, qualifier Q> |
| 7 | GLM_FUNC_QUALIFIER vec<L, T, Q> taylorCos(vec<L, T, Q> const& x) |
| 8 | { |
| 9 | return static_cast<T>(1) |
| 10 | - (x * x) * (1.f / 2.f) |
| 11 | + ((x * x) * (x * x)) * (1.f / 24.f) |
| 12 | - (((x * x) * (x * x)) * (x * x)) * (1.f / 720.f) |
| 13 | + (((x * x) * (x * x)) * ((x * x) * (x * x))) * (1.f / 40320.f); |
| 14 | } |
| 15 | |
| 16 | template<typename T> |
| 17 | GLM_FUNC_QUALIFIER T cos_52s(T x) |
| 18 | { |
| 19 | T const xx(x * x); |
| 20 | return (T(0.9999932946) + xx * (T(-0.4999124376) + xx * (T(0.0414877472) + xx * T(-0.0012712095)))); |
| 21 | } |
| 22 | |
| 23 | template<length_t L, typename T, qualifier Q> |
| 24 | GLM_FUNC_QUALIFIER vec<L, T, Q> cos_52s(vec<L, T, Q> const& x) |
| 25 | { |
| 26 | return detail::functor1<vec, L, T, T, Q>::call(cos_52s, x); |
| 27 | } |
| 28 | }//namespace detail |
| 29 | |
| 30 | // wrapAngle |
| 31 | template<typename T> |
| 32 | GLM_FUNC_QUALIFIER T wrapAngle(T angle) |
| 33 | { |
| 34 | return abs<T>(mod<T>(angle, two_pi<T>())); |
| 35 | } |
| 36 | |
| 37 | template<length_t L, typename T, qualifier Q> |
| 38 | GLM_FUNC_QUALIFIER vec<L, T, Q> wrapAngle(vec<L, T, Q> const& x) |
| 39 | { |
| 40 | return detail::functor1<vec, L, T, T, Q>::call(wrapAngle, x); |
| 41 | } |
| 42 | |
| 43 | // cos |
| 44 | template<typename T> |
| 45 | GLM_FUNC_QUALIFIER T fastCos(T x) |
| 46 | { |
| 47 | T const angle(wrapAngle<T>(x)); |
| 48 | |
| 49 | if(angle < half_pi<T>()) |
| 50 | return detail::cos_52s(angle); |
| 51 | if(angle < pi<T>()) |
| 52 | return -detail::cos_52s(pi<T>() - angle); |
| 53 | if(angle < (T(3) * half_pi<T>())) |
| 54 | return -detail::cos_52s(angle - pi<T>()); |
| 55 | |
| 56 | return detail::cos_52s(two_pi<T>() - angle); |
| 57 | } |
| 58 | |
| 59 | template<length_t L, typename T, qualifier Q> |
| 60 | GLM_FUNC_QUALIFIER vec<L, T, Q> fastCos(vec<L, T, Q> const& x) |
| 61 | { |
| 62 | return detail::functor1<vec, L, T, T, Q>::call(fastCos, x); |
| 63 | } |
| 64 | |
| 65 | // sin |
| 66 | template<typename T> |
| 67 | GLM_FUNC_QUALIFIER T fastSin(T x) |
| 68 | { |
| 69 | return fastCos<T>(half_pi<T>() - x); |
| 70 | } |
| 71 | |
| 72 | template<length_t L, typename T, qualifier Q> |
| 73 | GLM_FUNC_QUALIFIER vec<L, T, Q> fastSin(vec<L, T, Q> const& x) |
| 74 | { |
| 75 | return detail::functor1<vec, L, T, T, Q>::call(fastSin, x); |
| 76 | } |
| 77 | |
| 78 | // tan |
| 79 | template<typename T> |
| 80 | GLM_FUNC_QUALIFIER T fastTan(T x) |
| 81 | { |
| 82 | return x + (x * x * x * T(0.3333333333)) + (x * x * x * x * x * T(0.1333333333333)) + (x * x * x * x * x * x * x * T(0.0539682539)); |
| 83 | } |
| 84 | |
| 85 | template<length_t L, typename T, qualifier Q> |
| 86 | GLM_FUNC_QUALIFIER vec<L, T, Q> fastTan(vec<L, T, Q> const& x) |
| 87 | { |
| 88 | return detail::functor1<vec, L, T, T, Q>::call(fastTan, x); |
| 89 | } |
| 90 | |
| 91 | // asin |
| 92 | template<typename T> |
| 93 | GLM_FUNC_QUALIFIER T fastAsin(T x) |
| 94 | { |
| 95 | return x + (x * x * x * T(0.166666667)) + (x * x * x * x * x * T(0.075)) + (x * x * x * x * x * x * x * T(0.0446428571)) + (x * x * x * x * x * x * x * x * x * T(0.0303819444));// + (x * x * x * x * x * x * x * x * x * x * x * T(0.022372159)); |
| 96 | } |
| 97 | |
| 98 | template<length_t L, typename T, qualifier Q> |
| 99 | GLM_FUNC_QUALIFIER vec<L, T, Q> fastAsin(vec<L, T, Q> const& x) |
| 100 | { |
| 101 | return detail::functor1<vec, L, T, T, Q>::call(fastAsin, x); |
| 102 | } |
| 103 | |
| 104 | // acos |
| 105 | template<typename T> |
| 106 | GLM_FUNC_QUALIFIER T fastAcos(T x) |
| 107 | { |
| 108 | return T(1.5707963267948966192313216916398) - fastAsin(x); //(PI / 2) |
| 109 | } |
| 110 | |
| 111 | template<length_t L, typename T, qualifier Q> |
| 112 | GLM_FUNC_QUALIFIER vec<L, T, Q> fastAcos(vec<L, T, Q> const& x) |
| 113 | { |
| 114 | return detail::functor1<vec, L, T, T, Q>::call(fastAcos, x); |
| 115 | } |
| 116 | |
| 117 | // atan |
| 118 | template<typename T> |
| 119 | GLM_FUNC_QUALIFIER T fastAtan(T y, T x) |
| 120 | { |
| 121 | T sgn = sign(y) * sign(x); |
| 122 | return abs(fastAtan(y / x)) * sgn; |
| 123 | } |
| 124 | |
| 125 | template<length_t L, typename T, qualifier Q> |
| 126 | GLM_FUNC_QUALIFIER vec<L, T, Q> fastAtan(vec<L, T, Q> const& y, vec<L, T, Q> const& x) |
| 127 | { |
| 128 | return detail::functor2<vec, L, T, Q>::call(fastAtan, y, x); |
| 129 | } |
| 130 | |
| 131 | template<typename T> |
| 132 | GLM_FUNC_QUALIFIER T fastAtan(T x) |
| 133 | { |
| 134 | return x - (x * x * x * T(0.333333333333)) + (x * x * x * x * x * T(0.2)) - (x * x * x * x * x * x * x * T(0.1428571429)) + (x * x * x * x * x * x * x * x * x * T(0.111111111111)) - (x * x * x * x * x * x * x * x * x * x * x * T(0.0909090909)); |
| 135 | } |
| 136 | |
| 137 | template<length_t L, typename T, qualifier Q> |
| 138 | GLM_FUNC_QUALIFIER vec<L, T, Q> fastAtan(vec<L, T, Q> const& x) |
| 139 | { |
| 140 | return detail::functor1<vec, L, T, T, Q>::call(fastAtan, x); |
| 141 | } |
| 142 | }//namespace glm |