简体   繁体   中英

boost polygon intersection API is working in opposite way of what it should be

I am not sure why the boost polygon intersection in below code example is just giving the opposite output ie its giving areas which are OPPOSITE of intersection.

I don't know if something is wrong with my polygon data AS it all looks good to me (but not sure if you can spot anything odd).

You can uncomment the commented code to see how the 2 polygons look like. The output can be seen in file my_map.svg and it will just show the opposite of intersection between 2 polygons. Not sure why its behaving in reverse way.

#include <iostream>
#include <fstream>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>

int main()
{

    typedef boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > polygon;
 
    polygon a, b;

    boost::geometry::read_wkt("POLYGON((422.029 420.829,416.779 427.824,413.079 432.754,411.514 434.839,405.294 443.123,367.717 493.174,361.119 501.961,359.867 503.693,349.783 498.44,328.039 487.113,312.182 481.212,295.134 477.466,278.859 475.139,266.868 475.801,187.698 491.788,166.692 495.595,157.994 464.487,147.902 436.336,139.553 416.747,117.365 366.518,95.1775 316.288,68.2962 245.995,45.4972 177.281,31.9009 125.252,24.7675 98.0465,7.031 30.4037,-5.09537 -23.5814,-13.3492 -74.931,-22.0924 -132.107,-30.068 -226.135,-30.8215 -230.193,-33.1719 -318.815,-35.5218 -407.437,-19.2902 -403.222,36.0998 -393.283,126.809 -387.227,145.351 -390.15,164.088 -394.348,231.549 -417.759,299.009 -441.17,298.703 -456.121,302.675 -457.547,346.766 -473.386,395.71 -490.966,444.654 -508.547,456.541 -512.812,475.159 -513.201,481.397 -513.329,485.21 -513.408,490.793 -513.523,508.346 -513.874,508.437 -513.876,515.036 -514.009,517.093 -514.051,524.719 -514.205,604.376 -529.072,619.023 -527.544,640.877 -516.607,706.036 -517.941,771.196 -519.276,773.204 -519.323,773.291 -515.039,755.121 -444.833,734.542 -425.062,730.418 -414.227,750.154 -385.311,751.05 -303.546,749.413 -300.971,751.095 -299.408,803.104 -251.069,855.113 -202.731,892.855 -140.167,930.598 -77.6028,939.232 -69.3115,938.067 -67.6543,905.009 -20.5411,871.951 26.572,816.821 105.141,761.691 183.71,706.561 262.28,702.345 264.782,675.313 280.828,671.489 283.098,670.221 282.255,626.86 253.44,583.5 224.624,545.885 184.348,508.27 144.071,470.699 141.098,468.429 140.919,466.877 142.813,406.125 216.993,394.011 244.292,392.277 261.076,357.41 315.935,359.299 316.721,412.859 339.189,466.419 361.656,465.655 362.675,465.175 363.315,465.094 363.422,464.335 364.435,460.925 368.981,450.837 382.429,447.236 387.23,443.635 392.03,440.034 396.83,436.434 401.63,432.832 406.431,429.231 411.23,425.63 416.03,422.029 420.829))", a);


    boost::geometry::read_wkt("POLYGON((0 504,861 504,861 -0,0 -0,0 504))", b);

    std::deque<polygon> output;
    boost::geometry::intersection(a, b, output);


    // Declare a stream and an SVG mapper
    std::ofstream svg("my_map.svg");
    boost::geometry::svg_mapper<boost::geometry::model::d2::point_xy<double>> mapper(svg, 400, 400);

    // Add geometries such that all these geometries fit on the map
    //mapper.add(a);
    //mapper.add(b);
    mapper.add(output[0].outer());

    // Draw the geometries on the SVG map, using a specific SVG style
    //mapper.map(a, "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:2");
    //mapper.map(b, "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:2");
    mapper.map(output[0].outer(), "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:2");

    return 0;
}

The order of points is important.

You are using polygon model which has ClockWise paramter set by true by default.

Direction of points for polygon b satisfies this condition. But, for polygon a you are using counter clock wise. It can be corrected by boost::geometry::correct :

boost::geometry::read_wkt("POLYGON((422.029 420.829,508. ...",a);
boost::geometry::correct(a);

在此处输入图像描述

You're not getting opposite, but unspecified behaviour. That's because the orientation of the points is invalid:

Live On Coliru

#include <iostream>
#include <fstream>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>

namespace bg = boost::geometry;
namespace bgm = bg::model;

int main()
{
    using Point   = bgm::d2::point_xy<double>;
    using Polygon = bgm::polygon<Point>;
    using Multi   = bgm::multi_polygon<Polygon>;

    Polygon a;
    Polygon b;

    boost::geometry::read_wkt(
        "POLYGON((422.029 420.829,416.779 427.824,413.079 432.754,411.514 "
        "434.839,405.294 443.123,367.717 493.174,361.119 501.961,359.867 "
        "503.693,349.783 498.44,328.039 487.113,312.182 481.212,295.134 "
        "477.466,278.859 475.139,266.868 475.801,187.698 491.788,166.692 "
        "495.595,157.994 464.487,147.902 436.336,139.553 416.747,117.365 "
        "366.518,95.1775 316.288,68.2962 245.995,45.4972 177.281,31.9009 "
        "125.252,24.7675 98.0465,7.031 30.4037,-5.09537 -23.5814,-13.3492 "
        "-74.931,-22.0924 -132.107,-30.068 -226.135,-30.8215 -230.193,-33.1719 "
        "-318.815,-35.5218 -407.437,-19.2902 -403.222,36.0998 -393.283,126.809 "
        "-387.227,145.351 -390.15,164.088 -394.348,231.549 -417.759,299.009 "
        "-441.17,298.703 -456.121,302.675 -457.547,346.766 -473.386,395.71 "
        "-490.966,444.654 -508.547,456.541 -512.812,475.159 -513.201,481.397 "
        "-513.329,485.21 -513.408,490.793 -513.523,508.346 -513.874,508.437 "
        "-513.876,515.036 -514.009,517.093 -514.051,524.719 -514.205,604.376 "
        "-529.072,619.023 -527.544,640.877 -516.607,706.036 -517.941,771.196 "
        "-519.276,773.204 -519.323,773.291 -515.039,755.121 -444.833,734.542 "
        "-425.062,730.418 -414.227,750.154 -385.311,751.05 -303.546,749.413 "
        "-300.971,751.095 -299.408,803.104 -251.069,855.113 -202.731,892.855 "
        "-140.167,930.598 -77.6028,939.232 -69.3115,938.067 -67.6543,905.009 "
        "-20.5411,871.951 26.572,816.821 105.141,761.691 183.71,706.561 "
        "262.28,702.345 264.782,675.313 280.828,671.489 283.098,670.221 "
        "282.255,626.86 253.44,583.5 224.624,545.885 184.348,508.27 "
        "144.071,470.699 141.098,468.429 140.919,466.877 142.813,406.125 "
        "216.993,394.011 244.292,392.277 261.076,357.41 315.935,359.299 "
        "316.721,412.859 339.189,466.419 361.656,465.655 362.675,465.175 "
        "363.315,465.094 363.422,464.335 364.435,460.925 368.981,450.837 "
        "382.429,447.236 387.23,443.635 392.03,440.034 396.83,436.434 "
        "401.63,432.832 406.431,429.231 411.23,425.63 416.03,422.029 420.829))",
        a);
    bg::read_wkt("POLYGON((0 504,861 504,861 -0,0 -0,0 504))", b);

    if (std::string reason; !bg::is_valid(a, reason)) {
        std::cout << "Correcting a: " << reason << "\n";
        bg::correct(a);
        assert(bg::is_valid(a));
    }

    if (std::string reason; !bg::is_valid(b, reason)) {
        std::cout << "Correcting b: " << reason << "\n";
        bg::correct(b);
        assert(bg::is_valid(b));
    }

    Multi c;
    bg::intersection(a, b, c);

    {
        // Declare a stream and an SVG mapper
        std::ofstream svg("my_map.svg");
        bg::svg_mapper<Point> mapper(svg, 400, 400);

        // Add geometries such that all these geometries fit on the map
        mapper.add(a);
        mapper.add(b);
        mapper.add(c);

        // Draw the geometries on the SVG map, using a specific SVG style
        mapper.map(a, "fill-opacity:0.3;fill:rgb(51,0,0);stroke:rgb(51,0,0);stroke-width:2");
        mapper.map(b, "fill-opacity:0.3;fill:rgb(0,51,0);stroke:rgb(0,51,0);stroke-width:2");
        mapper.map(c, "fill-opacity:0.3;fill:rgb(0,0,51);stroke:rgb(0,0,51);stroke-width:2");
    }
}

Prints

Correcting a: Geometry has wrong orientation

And results in the following SVG:

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM