boostorg / geometry

Boost.Geometry - Generic Geometry Library | Requires C++14 since Boost 1.75
http://boost.org/libs/geometry
Boost Software License 1.0
458 stars 216 forks source link

Invalid result of sym_difference(). #515

Open awulkiew opened 6 years ago

awulkiew commented 6 years ago

Detected for several cases of sym_difference, e.g. difference.cpp test case intersect_holes_intersect_and_disjoint used in the example below:

#include <boost/geometry.hpp>
#include <iostream>

int main()
{
    namespace bg = boost::geometry;
    typedef bg::model::point<double, 2, bg::cs::cartesian> point;
    typedef bg::model::polygon<point> polygon;
    typedef bg::model::multi_polygon<polygon> multi_polygon;

    polygon g1, g2;
    multi_polygon result;

    bg::read_wkt("POLYGON((0 0,0 7,5 7,5 0,0 0),(2 2,3 2,3 3,2 3,2 2),(2 4,3 4,3 5,2 5,2 4))", g1);
    bg::read_wkt("POLYGON((1 1,1 6,6 6,6 1,1 1),(2.5 2.5,3.5 2.5,3.5 3.5,2.5 3.5,2.5 2.5))", g2);

    bg::sym_difference(g1, g2, result);

    std::cout << std::setprecision(10);
    std::cout << bg::wkt(result[3].outer()[4]) << std::endl;
    std::cout << bg::wkt(result[4].outer()[2]) << std::endl;

    std::cout << bg::relation(result[3], result[4]).str() << std::endl;

    return 0;
}

With develop branch and msvc-14.0 (Visual Studio 2015) x86 Debug mode the output is:

POINT(3 2.49999965)
POINT(3.00000035 2.5)
212101212

path885

which means that the interiors of polygons 3 and 4 in the result intersect (internally in relate get_turns correctly returns 2 crossing turns). Two equal points should be generated as a result of intersection of the holes of the input polygons. Two different points are generated instead.

Side note: ~this is not~ previously this was not detected by is_valid() due to a bug in this algorithm incorrectly using point_on_border() to check if interiors intersect.

awulkiew commented 5 years ago

@barendgehrels

awulkiew commented 5 years ago

difference() cases currently failing validity test are: