From 710e13a8e62015da18f7cbbfc9bc9d82b2807b54 Mon Sep 17 00:00:00 2001 From: Mathias Labeyrie Date: Wed, 5 Nov 2014 10:55:42 +0100 Subject: [PATCH] Much more precise fastCos and fastSin fastCos and fastSin had a max error of ~0.2 on [-pi pi]. The updated version is ~0.000007. --- glm/gtx/fast_trigonometry.hpp | 10 +++++++--- glm/gtx/fast_trigonometry.inl | 33 ++++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/glm/gtx/fast_trigonometry.hpp b/glm/gtx/fast_trigonometry.hpp index f89a6df6..17b04cfb 100644 --- a/glm/gtx/fast_trigonometry.hpp +++ b/glm/gtx/fast_trigonometry.hpp @@ -39,6 +39,7 @@ // Dependency: #include "../glm.hpp" +#include "../gtc/constants.hpp" #if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED)) # pragma message("GLM: GLM_GTX_fast_trigonometry extension included") @@ -49,14 +50,17 @@ namespace glm /// @addtogroup gtx_fast_trigonometry /// @{ - //! Faster than the common sin function but less accurate. - //! Defined between -2pi and 2pi. + //! Wrap an angle to [0 2pi[ //! From GLM_GTX_fast_trigonometry extension. template + GLM_FUNC_DECL T wrapAngle(const T& angle); + + //! Faster than the common sin function but less accurate. + //! From GLM_GTX_fast_trigonometry extension. + template GLM_FUNC_DECL T fastSin(const T& angle); //! Faster than the common cos function but less accurate. - //! Defined between -2pi and 2pi. //! From GLM_GTX_fast_trigonometry extension. template GLM_FUNC_DECL T fastCos(const T& angle); diff --git a/glm/gtx/fast_trigonometry.inl b/glm/gtx/fast_trigonometry.inl index b68e8fd5..632be5d2 100644 --- a/glm/gtx/fast_trigonometry.inl +++ b/glm/gtx/fast_trigonometry.inl @@ -9,24 +9,47 @@ namespace glm { - // sin template - GLM_FUNC_QUALIFIER T fastSin(T const & x) + GLM_FUNC_QUALIFIER T wrapAngle(T const & angle) { - return x - ((x * x * x) / T(6)) + ((x * x * x * x * x) / T(120)) - ((x * x * x * x * x * x * x) / T(5040)); + T result = angle - floor(angle * one_over_two_pi()) * two_pi(); + result = result > T(0) ? result : -result; + return result; } - VECTORIZE_VEC(fastSin) + VECTORIZE_VEC(wrapAngle) + + template + GLM_FUNC_QUALIFIER T cos_52s(T const & x) + { + T const xx(x * x); + return (T(0.9999932946) + xx * (T(-0.4999124376) + xx * (T(0.0414877472) + xx * T(-0.0012712095)))); + } + + VECTORIZE_VEC(cos_52s) // cos template GLM_FUNC_QUALIFIER T fastCos(T const & x) { - return T(1) - (x * x * T(0.5)) + (x * x * x * x * T(0.041666666666)) - (x * x * x * x * x * x * T(0.00138888888888)); + T const angle(wrapAngle(x)); + if(angle()) return cos_52s(angle); + if(angle()) return -cos_52s(pi() - angle); + if(angle<(T(3) * half_pi())) return -cos_52s(angle - pi()); + return cos_52s(two_pi() - angle); } VECTORIZE_VEC(fastCos) + // sin + template + GLM_FUNC_QUALIFIER T fastSin(T const & x) + { + return fastCos(half_pi() - x); + } + + VECTORIZE_VEC(fastSin) + // tan template GLM_FUNC_QUALIFIER T fastTan(T const & x)