|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r73599 - in trunk/boost/geometry: algorithms/detail algorithms/detail/overlay strategies/cartesian
From: barend.gehrels_at_[hidden]
Date: 2011-08-07 12:46:34
Author: barendgehrels
Date: 2011-08-07 12:46:33 EDT (Sun, 07 Aug 2011)
New Revision: 73599
URL: http://svn.boost.org/trac/boost/changeset/73599
Log:
Fixed performance issue on self intersections
Text files modified:
trunk/boost/geometry/algorithms/detail/has_self_intersections.hpp | 2
trunk/boost/geometry/algorithms/detail/overlay/get_turns.hpp | 11 +--
trunk/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp | 112 +++++++++++++++++++++++++++------------
trunk/boost/geometry/strategies/cartesian/cart_intersect.hpp | 2
4 files changed, 84 insertions(+), 43 deletions(-)
Modified: trunk/boost/geometry/algorithms/detail/has_self_intersections.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/has_self_intersections.hpp (original)
+++ trunk/boost/geometry/algorithms/detail/has_self_intersections.hpp 2011-08-07 12:46:33 EDT (Sun, 07 Aug 2011)
@@ -62,7 +62,7 @@
typedef typename point_type<Geometry>::type point_type;
typedef detail::overlay::turn_info<point_type> turn_info;
std::deque<turn_info> turns;
- detail::get_turns::no_interrupt_policy policy;
+ detail::disjoint::disjoint_interrupt_policy policy;
geometry::self_turns<detail::overlay::assign_null_policy>(geometry, turns, policy);
#ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
Modified: trunk/boost/geometry/algorithms/detail/overlay/get_turns.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/overlay/get_turns.hpp (original)
+++ trunk/boost/geometry/algorithms/detail/overlay/get_turns.hpp 2011-08-07 12:46:33 EDT (Sun, 07 Aug 2011)
@@ -147,11 +147,8 @@
>::type,
areal_tag
>::value
- &&
- (
- (index2 == 0 && index1 >= n - 2)
- || (index1 == 0 && index2 >= n - 2)
- )
+ && index1 == 0
+ && index2 >= n - 2
;
}
@@ -232,8 +229,8 @@
// Also skip if index1 < index2 to avoid getting all
// intersections twice (only do this on same source!)
- skip = index2 >= index1
- || ndi1 == ndi2 + 1
+ skip = index1 >= index2
+ || ndi2 == ndi1 + 1
|| neighbouring<Geometry1>(sec1, index1, index2)
;
}
Modified: trunk/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp (original)
+++ trunk/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp 2011-08-07 12:46:33 EDT (Sun, 07 Aug 2011)
@@ -19,6 +19,7 @@
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/detail/disjoint.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
#include <boost/geometry/geometries/box.hpp>
@@ -31,6 +32,60 @@
namespace detail { namespace self_get_turn_points
{
+class self_ip_exception : public geometry::exception {};
+
+template
+<
+ typename Geometry,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct self_section_visitor
+{
+ Geometry const& m_geometry;
+ Turns& m_turns;
+ InterruptPolicy& m_interrupt_policy;
+
+ inline self_section_visitor(Geometry const& g,
+ Turns& turns, InterruptPolicy& ip)
+ : m_geometry(g)
+ , m_turns(turns)
+ , m_interrupt_policy(ip)
+ {}
+
+ template <typename Section>
+ inline bool apply(Section const& sec1, Section const& sec2)
+ {
+ if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box)
+ && ! sec1.duplicate
+ && ! sec2.duplicate)
+ {
+ detail::get_turns::get_turns_in_sections
+ <
+ Geometry, Geometry,
+ false, false,
+ Section, Section,
+ Turns, TurnPolicy,
+ InterruptPolicy
+ >::apply(
+ 0, m_geometry, sec1,
+ 0, m_geometry, sec2,
+ m_turns, m_interrupt_policy);
+ }
+ if (m_interrupt_policy.has_intersections)
+ {
+ // TODO: we should give partition an interrupt policy.
+ // Now we throw, and catch below, to stop the partition loop.
+ throw self_ip_exception();
+ }
+ return true;
+ }
+
+};
+
+
+
template
<
typename Geometry,
@@ -45,49 +100,38 @@
Turns& turns,
InterruptPolicy& interrupt_policy)
{
+ typedef model::box
+ <
+ typename geometry::point_type<Geometry>::type
+ > box_type;
typedef typename geometry::sections
<
- model::box <typename geometry::point_type<Geometry>::type>,
- 1
+ box_type, 1
> sections_type;
sections_type sec;
geometry::sectionalize<false>(geometry, sec);
- for (typename boost::range_iterator<sections_type const>::type
- it1 = sec.begin();
- it1 != sec.end();
- ++it1)
+ self_section_visitor
+ <
+ Geometry,
+ Turns, TurnPolicy, InterruptPolicy
+ > visitor(geometry, turns, interrupt_policy);
+
+ try
{
- for (typename boost::range_iterator<sections_type const>::type
- it2 = sec.begin();
- it2 != sec.end();
- ++it2)
- {
- if (! geometry::detail::disjoint::disjoint_box_box(
- it1->bounding_box, it2->bounding_box)
- && ! it1->duplicate
- && ! it2->duplicate
- )
- {
- if (! geometry::detail::get_turns::get_turns_in_sections
- <
- Geometry, Geometry,
- false, false,
- typename boost::range_value<sections_type>::type,
- typename boost::range_value<sections_type>::type,
- Turns, TurnPolicy,
- InterruptPolicy
- >::apply(
- 0, geometry, *it1,
- 0, geometry, *it2,
- turns, interrupt_policy))
- {
- return false;
- }
- }
- }
+ geometry::partition
+ <
+ box_type,
+ detail::get_turns::get_section_box,
+ detail::get_turns::ovelaps_section_box
+ >::apply(sec, visitor);
}
+ catch(self_ip_exception const& )
+ {
+ return false;
+ }
+
return true;
}
};
Modified: trunk/boost/geometry/strategies/cartesian/cart_intersect.hpp
==============================================================================
--- trunk/boost/geometry/strategies/cartesian/cart_intersect.hpp (original)
+++ trunk/boost/geometry/strategies/cartesian/cart_intersect.hpp 2011-08-07 12:46:33 EDT (Sun, 07 Aug 2011)
@@ -193,7 +193,7 @@
bool collinear = sides.collinear();
- // Get the same type, but at least a double (also used for divisions
+ // Get the same type, but at least a double (also used for divisions)
typedef typename select_most_precise
<
coordinate_type, double
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