|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r72029 - in trunk/boost/geometry: algorithms algorithms/detail algorithms/detail/equals util
From: barend.gehrels_at_[hidden]
Date: 2011-05-18 14:06:36
Author: barendgehrels
Date: 2011-05-18 14:06:34 EDT (Wed, 18 May 2011)
New Revision: 72029
URL: http://svn.boost.org/trac/boost/changeset/72029
Log:
Fixed geometry::equals for high precision
Text files modified:
trunk/boost/geometry/algorithms/detail/equals/collect_vectors.hpp | 29 +++++++++++++++++++----------
trunk/boost/geometry/algorithms/detail/partition.hpp | 2 +-
trunk/boost/geometry/algorithms/equals.hpp | 5 +----
trunk/boost/geometry/util/math.hpp | 35 +++++++++++++++++++++++++++++------
4 files changed, 50 insertions(+), 21 deletions(-)
Modified: trunk/boost/geometry/algorithms/detail/equals/collect_vectors.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/equals/collect_vectors.hpp (original)
+++ trunk/boost/geometry/algorithms/detail/equals/collect_vectors.hpp 2011-05-18 14:06:34 EDT (Wed, 18 May 2011)
@@ -14,8 +14,6 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP
-#include <algorithm>
-#include <deque>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/range.hpp>
@@ -26,9 +24,8 @@
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/strategies/side.hpp>
-#include <boost/geometry/util/select_most_precise.hpp>
+#include <boost/geometry/util/math.hpp>
@@ -41,10 +38,10 @@
{
typedef T type;
- collected_vector()
+ inline collected_vector()
{}
- collected_vector(T const& px, T const& py,
+ inline collected_vector(T const& px, T const& py,
T const& pdx, T const& pdy)
: x(px)
, y(py)
@@ -58,7 +55,8 @@
T dx, dy;
T dx_0, dy_0;
- bool operator<(collected_vector<T> const& other) const
+ // For sorting
+ inline bool operator<(collected_vector<T> const& other) const
{
if (math::equals(x, other.x))
{
@@ -77,10 +75,15 @@
inline bool same_direction(collected_vector<T> const& other) const
{
- return math::equals(dx, other.dx)
- && math::equals(dy, other.dy);
+ // For high precision arithmetic, we have to be
+ // more relaxed then using ==
+ // Because 2/sqrt( (0,0)<->(2,2) ) == 1/sqrt( (0,0)<->(1,1) )
+ // is not always true (at least, it is not for ttmath)
+ return math::equals_with_epsilon(dx, other.dx)
+ && math::equals_with_epsilon(dy, other.dy);
}
+ // For std::equals
inline bool operator==(collected_vector<T> const& other) const
{
return math::equals(x, other.x)
@@ -145,7 +148,13 @@
first = false;
}
}
- // TODO: if first one has same direction as last one, remove first one...
+
+ // If first one has same direction as last one, remove first one
+ if (boost::size(collection) > 1
+ && collection.front().same_direction(collection.back()))
+ {
+ collection.erase(collection.begin());
+ }
}
};
Modified: trunk/boost/geometry/algorithms/detail/partition.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/partition.hpp (original)
+++ trunk/boost/geometry/algorithms/detail/partition.hpp 2011-05-18 14:06:34 EDT (Wed, 18 May 2011)
@@ -79,7 +79,7 @@
}
-// Match collection 1 with collection 2
+// Match collection with itself
template <typename InputCollection, typename Policy>
static inline void handle_one(InputCollection const& collection,
index_vector_type const& input,
Modified: trunk/boost/geometry/algorithms/equals.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/equals.hpp (original)
+++ trunk/boost/geometry/algorithms/equals.hpp 2011-05-18 14:06:34 EDT (Wed, 18 May 2011)
@@ -15,9 +15,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_EQUALS_HPP
-
#include <cstddef>
-#include <deque>
#include <vector>
#include <boost/mpl/if.hpp>
@@ -139,8 +137,7 @@
std::sort(c2.begin(), c2.end());
// Just check if these vectors are equal.
- return c1.size() == c2.size()
- && std::equal(c1.begin(), c1.end(), c2.begin());
+ return std::equal(c1.begin(), c1.end(), c2.begin());
}
};
Modified: trunk/boost/geometry/util/math.hpp
==============================================================================
--- trunk/boost/geometry/util/math.hpp (original)
+++ trunk/boost/geometry/util/math.hpp 2011-05-18 14:06:34 EDT (Wed, 18 May 2011)
@@ -32,27 +32,38 @@
{
-template <typename T, bool Floating>
+template <typename Type, bool, typename TypeForEpsilon = Type>
struct equals
{
- static inline bool apply(T const& a, T const& b)
+ static inline bool apply(Type const& a, Type const& b)
{
return a == b;
}
};
-template <typename T>
-struct equals<T, true>
+template <typename Type, typename TypeForEpsilon>
+struct equals<Type, true, TypeForEpsilon>
{
- static inline bool apply(T const& a, T const& b)
+ static inline bool apply(Type const& a, Type const& b)
{
// See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17,
// FUTURE: replace by some boost tool or boost::test::close_at_tolerance
- return std::abs(a - b) <= std::numeric_limits<T>::epsilon() * std::abs(a);
+ Type const epsilon = std::numeric_limits<TypeForEpsilon>::epsilon();
+ return abs(a - b) <= epsilon * abs(a);
}
};
+template <typename Type, bool>
+struct equals_with_epsilon {};
+
+template <typename Type>
+struct equals_with_epsilon<Type, false> : public equals<Type, true, double> {};
+
+template <typename Type>
+struct equals_with_epsilon<Type, true> : public equals<Type, true> {};
+
+
/*!
\brief Short construct to enable partial specialization for PI, currently not possible in Math.
*/
@@ -101,6 +112,18 @@
>::apply(a, b);
}
+template <typename T1, typename T2>
+inline bool equals_with_epsilon(T1 const& a, T2 const& b)
+{
+ typedef typename select_most_precise<T1, T2>::type select_type;
+ return detail::equals_with_epsilon
+ <
+ select_type,
+ boost::is_floating_point<select_type>::type::value
+ >::apply(a, b);
+}
+
+
double const d2r = geometry::math::pi<double>() / 180.0;
double const r2d = 1.0 / d2r;
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk