Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77337 - in trunk/boost/geometry/strategies: . cartesian
From: barend.gehrels_at_[hidden]
Date: 2012-03-14 14:57:47


Author: barendgehrels
Date: 2012-03-14 14:57:46 EDT (Wed, 14 Mar 2012)
New Revision: 77337
URL: http://svn.boost.org/trac/boost/changeset/77337

Log:
[geometry] fix for robustness issue on touch with r > 1
Text files modified:
   trunk/boost/geometry/strategies/cartesian/cart_intersect.hpp | 68 +++++++++++++++++++++------------------
   trunk/boost/geometry/strategies/side_info.hpp | 7 ++++
   2 files changed, 44 insertions(+), 31 deletions(-)

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 2012-03-14 14:57:46 EDT (Wed, 14 Mar 2012)
@@ -204,41 +204,47 @@
                                 promoted_type const one = 1;
                                 promoted_type const epsilon = std::numeric_limits<double>::epsilon();
 
- if (sides.crossing() && math::abs(da-d) < 0.1)
+ if (r < zero || r > one)
                 {
- // ROBUSTNESS: the r value can in epsilon-cases be 1.14, while (with perfect arithmetic)
- // it should be one. If segments are crossing (we can see that with the sides)
- // and one is inside the other, there must be an intersection point.
- // We correct for that.
- // TODO: find more cases (this only solves case called ggl_list_20110820_christophe in unit tests
- if (r > one)
+ if (sides.crossing() || sides.touching())
                     {
- // std::cout << "ROBUSTNESS: correction of r " << r << std::endl;
- r = one;
- }
- else if (r < zero)
- {
- // std::cout << "ROBUSTNESS: correction of r " << r << std::endl;
- r = zero;
+ // ROBUSTNESS: the r value can in epsilon-cases be 1.14, while (with perfect arithmetic)
+ // it should be one. If segments are crossing (we can see that with the sides)
+ // and one is inside the other, there must be an intersection point.
+ // We correct for that.
+ // This is (only) in case #ggl_list_20110820_christophe in unit tests
+ // If segments are touching (two sides zero), of course they should intersect
+ // This is (only) in case #buffer_rt_i in the unit tests)
+ // TODO: find more cases
+ if (r > one)
+ {
+ // std::cout << "ROBUSTNESS: correction of r " << r << std::endl;
+ r = one;
+ }
+ else if (r < zero)
+ {
+ // std::cout << "ROBUSTNESS: correction of r " << r << std::endl;
+ r = zero;
+ }
                     }
+
+ if (r < zero)
+ {
+ if (r < -epsilon)
+ {
+ return Policy::disjoint();
+ }
+ r = zero;
+ }
+ else if (r > one)
+ {
+ if (r > one + epsilon)
+ {
+ return Policy::disjoint();
+ }
+ r = one;
+ }
                 }
-
- if (r < zero)
- {
- if (r < -epsilon)
- {
- return Policy::disjoint();
- }
- r = zero;
- }
- else if (r > one)
- {
- if (r > one + epsilon)
- {
- return Policy::disjoint();
- }
- r = one;
- }
                         }
                 }
 

Modified: trunk/boost/geometry/strategies/side_info.hpp
==============================================================================
--- trunk/boost/geometry/strategies/side_info.hpp (original)
+++ trunk/boost/geometry/strategies/side_info.hpp 2012-03-14 14:57:46 EDT (Wed, 14 Mar 2012)
@@ -73,6 +73,13 @@
             && sides[1].first * sides[1].second == -1;
     }
 
+ inline bool touching() const
+ {
+ return (sides[0].first * sides[1].first == -1
+ && sides[0].second == 0 && sides[1].second == 0)
+ || (sides[1].first * sides[0].first == -1
+ && sides[1].second == 0 && sides[0].second == 0);
+ }
 
     template <int Which>
     inline bool zero() const


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