]> git.sesse.net Git - casparcg/blob - dependencies/boost/boost/geometry/util/math.hpp
Manually merged pull request #222
[casparcg] / dependencies / boost / boost / geometry / util / math.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
6
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
9
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
13
14 #ifndef BOOST_GEOMETRY_UTIL_MATH_HPP
15 #define BOOST_GEOMETRY_UTIL_MATH_HPP
16
17 #include <cmath>
18 #include <limits>
19
20 #include <boost/math/constants/constants.hpp>
21
22 #include <boost/geometry/util/select_most_precise.hpp>
23
24 namespace boost { namespace geometry
25 {
26
27 namespace math
28 {
29
30 #ifndef DOXYGEN_NO_DETAIL
31 namespace detail
32 {
33
34
35 template <typename Type, bool IsFloatingPoint>
36 struct equals
37 {
38     static inline bool apply(Type const& a, Type const& b)
39     {
40         return a == b;
41     }
42 };
43
44 template <typename Type>
45 struct equals<Type, true>
46 {
47     static inline bool apply(Type const& a, Type const& b)
48     {
49         // See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17,
50         // FUTURE: replace by some boost tool or boost::test::close_at_tolerance
51         return std::abs(a - b) <= std::numeric_limits<Type>::epsilon() * std::abs(a);
52     }
53 };
54
55
56 template <typename Type, bool IsFloatingPoint> 
57 struct equals_with_epsilon : public equals<Type, IsFloatingPoint> {};
58
59
60 /*!
61 \brief Short construct to enable partial specialization for PI, currently not possible in Math.
62 */
63 template <typename T>
64 struct define_pi
65 {
66     static inline T apply()
67     {
68         // Default calls Boost.Math
69         return boost::math::constants::pi<T>();
70     }
71 };
72
73
74 } // namespace detail
75 #endif
76
77
78 template <typename T>
79 inline T pi() { return detail::define_pi<T>::apply(); }
80
81
82 // Maybe replace this by boost equals or boost ublas numeric equals or so
83
84 /*!
85     \brief returns true if both arguments are equal.
86     \ingroup utility
87     \param a first argument
88     \param b second argument
89     \return true if a == b
90     \note If both a and b are of an integral type, comparison is done by ==.
91     If one of the types is floating point, comparison is done by abs and
92     comparing with epsilon. If one of the types is non-fundamental, it might
93     be a high-precision number and comparison is done using the == operator
94     of that class.
95 */
96
97 template <typename T1, typename T2>
98 inline bool equals(T1 const& a, T2 const& b)
99 {
100     typedef typename select_most_precise<T1, T2>::type select_type;
101     return detail::equals
102         <
103             select_type,
104             boost::is_floating_point<select_type>::type::value
105         >::apply(a, b);
106 }
107
108 template <typename T1, typename T2>
109 inline bool equals_with_epsilon(T1 const& a, T2 const& b)
110 {
111     typedef typename select_most_precise<T1, T2>::type select_type;
112     return detail::equals_with_epsilon
113         <
114             select_type, 
115             boost::is_floating_point<select_type>::type::value
116         >::apply(a, b);
117 }
118
119
120
121 double const d2r = geometry::math::pi<double>() / 180.0;
122 double const r2d = 1.0 / d2r;
123
124 /*!
125     \brief Calculates the haversine of an angle
126     \ingroup utility
127     \note See http://en.wikipedia.org/wiki/Haversine_formula
128     haversin(alpha) = sin2(alpha/2)
129 */
130 template <typename T>
131 inline T hav(T const& theta)
132 {
133     T const half = T(0.5);
134     T const sn = sin(half * theta);
135     return sn * sn;
136 }
137
138 /*!
139 \brief Short utility to return the square
140 \ingroup utility
141 \param value Value to calculate the square from
142 \return The squared value
143 */
144 template <typename T>
145 inline T sqr(T const& value)
146 {
147     return value * value;
148 }
149
150
151 /*!
152 \brief Short utility to workaround gcc/clang problem that abs is converting to integer
153 \ingroup utility
154 */
155 template<typename T>
156 inline T abs(const T& t)
157 {
158     using std::abs;
159     return abs(t);
160 }
161
162
163 } // namespace math
164
165
166 }} // namespace boost::geometry
167
168 #endif // BOOST_GEOMETRY_UTIL_MATH_HPP