From 8c23e809a49b4e6a9acd91e723733b29148815f2 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Fri, 4 May 2012 22:13:17 +0900 Subject: [PATCH] add sprout::atan --- sprout/complex.hpp | 2 +- sprout/darkroom/objects/sphere.hpp | 2 +- sprout/math/atan.hpp | 83 ++++++++++++++++++++++++++++++ sprout/math/constants.hpp | 11 +++- sprout/math/sin.hpp | 2 +- sprout/math/trigonometric.hpp | 1 + 6 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 sprout/math/atan.hpp diff --git a/sprout/complex.hpp b/sprout/complex.hpp index d4d45138..41a92e40 100644 --- a/sprout/complex.hpp +++ b/sprout/complex.hpp @@ -361,7 +361,7 @@ namespace sprout { namespace detail { template SPROUT_CONSTEXPR sprout::complex acos_impl(sprout::complex const& t) { - return sprout::complex(sprout::math::pi_div_two() - t.real(), -t.imag()); + return sprout::complex(sprout::math::half_pi() - t.real(), -t.imag()); } } // namespace detail template diff --git a/sprout/darkroom/objects/sphere.hpp b/sprout/darkroom/objects/sphere.hpp index 84a2c8fa..6d9cc512 100644 --- a/sprout/darkroom/objects/sphere.hpp +++ b/sprout/darkroom/objects/sphere.hpp @@ -164,7 +164,7 @@ namespace sprout { + sprout::darkroom::coords::z(normal) * sprout::darkroom::coords::z(normal) ) ) - / sprout::math::pi_div_two() + / sprout::math::half_pi() ) ); } diff --git a/sprout/math/atan.hpp b/sprout/math/atan.hpp new file mode 100644 index 00000000..470e7b6f --- /dev/null +++ b/sprout/math/atan.hpp @@ -0,0 +1,83 @@ +#ifndef SPROUT_MATH_ATAN_HPP +#define SPROUT_MATH_ATAN_HPP + +#include +#include +#include +#include +#include +#include +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +# include +#endif + +namespace sprout { + namespace math { + namespace detail { + template + inline SPROUT_CONSTEXPR T + atan_impl_2(T x, T tmp, std::size_t n, T x2n1) { + return n > sprout::math::factorial_limit() ? tmp + : sprout::math::detail::atan_impl_2( + x, + tmp + (n % 2 ? -1 : 1) * x2n1 / (2 * n + 1), + n + 1, + x2n1 * x * x + ) + ; + } + template + inline SPROUT_CONSTEXPR T + atan_impl_1(T x) { + return sprout::math::detail::atan_impl_2( + x, + x, + 1, + x * x * x + ); + } + template + inline SPROUT_CONSTEXPR T + atan_impl(T x) { + return x > sprout::math::root_two() + 1 + ? sprout::math::half_pi() - sprout::math::detail::atan_impl_1(1 / x) + : x > sprout::math::root_two() - 1 + ? sprout::math::quarter_pi() + sprout::math::detail::atan_impl_1((x - 1) / (x + 1)) + : sprout::math::detail::atan_impl_1(x) + ; + } + + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + atan(FloatType x) { + typedef double type; + return static_cast( + x < 0 ? -sprout::math::detail::atan_impl(static_cast(-x)) + : sprout::math::detail::atan_impl(static_cast(x)) + ); + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR double + atan(IntType x) { + return sprout::math::detail::atan(static_cast(x)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::atan; +# else + using sprout::math::detail::atan; +# endif + } // namespace math + + using sprout::math::atan; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_ATAN_HPP diff --git a/sprout/math/constants.hpp b/sprout/math/constants.hpp index 64a9298b..272b1418 100644 --- a/sprout/math/constants.hpp +++ b/sprout/math/constants.hpp @@ -13,13 +13,20 @@ namespace sprout { return 3.141592653589793238462643383279502884197169399375105820974944L; } // - // pi_div_two + // half_pi // template - inline SPROUT_CONSTEXPR T pi_div_two() { + inline SPROUT_CONSTEXPR T half_pi() { return 1.570796326794896619231321691639751442098584699687552910487472L; } // + // quarter_pi + // + template + inline SPROUT_CONSTEXPR T quarter_pi() { + return 0.785398163397448309615660845819875721049292349843776455243736L; + } + // // root_two // template diff --git a/sprout/math/sin.hpp b/sprout/math/sin.hpp index 2c13ce44..cfc68c65 100644 --- a/sprout/math/sin.hpp +++ b/sprout/math/sin.hpp @@ -19,7 +19,7 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType sin(FloatType x) { - return -sprout::math::detail::cos(x + sprout::math::pi_div_two()); + return -sprout::math::detail::cos(x + sprout::math::half_pi()); } template< diff --git a/sprout/math/trigonometric.hpp b/sprout/math/trigonometric.hpp index 78e0130c..e4203bfa 100644 --- a/sprout/math/trigonometric.hpp +++ b/sprout/math/trigonometric.hpp @@ -4,5 +4,6 @@ #include #include #include +#include #endif // #ifndef SPROUT_MATH_TRIGONOMETRIC_HPP