diff options
Diffstat (limited to 'boost/geometry/util/math.hpp')
-rw-r--r-- | boost/geometry/util/math.hpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/boost/geometry/util/math.hpp b/boost/geometry/util/math.hpp index aed930dd97..dfbd5c9254 100644 --- a/boost/geometry/util/math.hpp +++ b/boost/geometry/util/math.hpp @@ -9,6 +9,7 @@ // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle +// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -772,6 +773,107 @@ inline Result rounding_cast(T const& v) } /*! +\brief Evaluate the sine and cosine function with the argument in degrees +\note The results obey exactly the elementary properties of the trigonometric + functions, e.g., sin 9° = cos 81° = − sin 123456789°. + If x = −0, then \e sinx = −0; this is the only case where + −0 is returned. +*/ +template<typename T> +inline void sin_cos_degrees(T const& x, + T & sinx, + T & cosx) +{ + // In order to minimize round-off errors, this function exactly reduces + // the argument to the range [-45, 45] before converting it to radians. + T remainder; int quotient; + + remainder = math::mod(x, T(360)); + quotient = floor(remainder / 90 + T(0.5)); + remainder -= 90 * quotient; + + // Convert to radians. + remainder *= d2r<T>(); + + T s = sin(remainder), c = cos(remainder); + + switch (unsigned(quotient) & 3U) + { + case 0U: sinx = s; cosx = c; break; + case 1U: sinx = c; cosx = -s; break; + case 2U: sinx = -s; cosx = -c; break; + default: sinx = -c; cosx = s; break; // case 3U + } + + // Set sign of 0 results. -0 only produced for sin(-0). + if (x != 0) + { + sinx += T(0); cosx += T(0); + } +} + +/*! +\brief Round off a given angle +*/ +template<typename T> +inline T round_angle(T x) { + static const T z = 1/T(16); + + if (x == 0) + { + return 0; + } + + T y = math::abs(x); + + // z - (z - y) must not be simplified to y. + y = y < z ? z - (z - y) : y; + + return x < 0 ? -y : y; +} + +/* +\brief Evaluate the polynomial in x using Horner's method. +*/ +// TODO: adl1995 - Merge these functions with formulas/area_formulas.hpp +// i.e. place them in one file. +template <typename NT, typename IteratorType> +inline NT horner_evaluate(NT x, + IteratorType begin, + IteratorType end) +{ + NT result(0); + IteratorType it = end; + do + { + result = result * x + *--it; + } + while (it != begin); + return result; +} + +/* +\brief Evaluate the polynomial. +*/ +template<typename IteratorType, typename CT> +inline CT polyval(IteratorType first, + IteratorType last, + const CT eps) +{ + int N = std::distance(first, last) - 1; + int index = 0; + + CT y = N < 0 ? 0 : *(first + (index++)); + + while (--N >= 0) + { + y = y * eps + *(first + (index++)); + } + + return y; +} + +/* \brief Short utility to calculate the power \ingroup utility */ |