1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
14 #ifndef BOOST_GEOMETRY_UTIL_MATH_HPP
15 #define BOOST_GEOMETRY_UTIL_MATH_HPP
20 #include <boost/math/constants/constants.hpp>
22 #include <boost/geometry/util/select_most_precise.hpp>
24 namespace boost { namespace geometry
30 #ifndef DOXYGEN_NO_DETAIL
35 template <typename Type, bool IsFloatingPoint>
38 static inline bool apply(Type const& a, Type const& b)
44 template <typename Type>
45 struct equals<Type, true>
47 static inline bool apply(Type const& a, Type const& b)
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);
56 template <typename Type, bool IsFloatingPoint>
57 struct equals_with_epsilon : public equals<Type, IsFloatingPoint> {};
61 \brief Short construct to enable partial specialization for PI, currently not possible in Math.
66 static inline T apply()
68 // Default calls Boost.Math
69 return boost::math::constants::pi<T>();
79 inline T pi() { return detail::define_pi<T>::apply(); }
82 // Maybe replace this by boost equals or boost ublas numeric equals or so
85 \brief returns true if both arguments are equal.
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
97 template <typename T1, typename T2>
98 inline bool equals(T1 const& a, T2 const& b)
100 typedef typename select_most_precise<T1, T2>::type select_type;
101 return detail::equals
104 boost::is_floating_point<select_type>::type::value
108 template <typename T1, typename T2>
109 inline bool equals_with_epsilon(T1 const& a, T2 const& b)
111 typedef typename select_most_precise<T1, T2>::type select_type;
112 return detail::equals_with_epsilon
115 boost::is_floating_point<select_type>::type::value
121 double const d2r = geometry::math::pi<double>() / 180.0;
122 double const r2d = 1.0 / d2r;
125 \brief Calculates the haversine of an angle
127 \note See http://en.wikipedia.org/wiki/Haversine_formula
128 haversin(alpha) = sin2(alpha/2)
130 template <typename T>
131 inline T hav(T const& theta)
133 T const half = T(0.5);
134 T const sn = sin(half * theta);
139 \brief Short utility to return the square
141 \param value Value to calculate the square from
142 \return The squared value
144 template <typename T>
145 inline T sqr(T const& value)
147 return value * value;
152 \brief Short utility to workaround gcc/clang problem that abs is converting to integer
156 inline T abs(const T& t)
166 }} // namespace boost::geometry
168 #endif // BOOST_GEOMETRY_UTIL_MATH_HPP