Boost geometry intersection does not output correctly

这一生的挚爱 提交于 2021-02-11 15:10:49

问题


From the following code I calculate the intersection of two polygons. I hope the output can be NULL if it is not polygon. However the output is (((240, 52.9999), (240, 53), (240, 53), (240, 52.9999))). This is not a polygon. Is there any way to check whether the output is really a polygon??

#include <iostream>
#include <deque>
#include <vector>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/geometry/algorithms/append.hpp>

#include <algorithm> // for reverse, unique
#include <iostream>
#include <string>


int main()
{
   typedef boost::geometry::model::d2::point_xy<double,    boost::geometry::cs::cartesian> point_2d;
   typedef boost::geometry::model::polygon<point_2d> polygon_2d;

    polygon_2d green;
    boost::geometry::append(green, point_2d(286.188, 90.9575));
    boost::geometry::append(green, point_2d(274.902, 56.2215));
    boost::geometry::append(green, point_2d(274.238, 55.7393));
    boost::geometry::append(green, point_2d(246.908, 51.9765));
    boost::geometry::append(green, point_2d(194.477, 59.7441));
    boost::geometry::append(green, point_2d(159.213, 101.141));
    boost::geometry::append(green, point_2d(203.576, 149.537));
    boost::geometry::append(green, point_2d(286.188, 90.9575));

    polygon_2d blue;
    boost::geometry::append(blue, point_2d(240, 53));
    boost::geometry::append(blue, point_2d(240, -53));
    boost::geometry::append(blue, point_2d(-60, -53));
    boost::geometry::append(blue, point_2d(-60, 53));
    boost::geometry::append(blue, point_2d(240, 53));

    boost::geometry::correct(green);
    boost::geometry::correct(blue);

    std::vector<polygon_2d> output;
    boost::geometry::intersection(green, blue, output);

    std::cout << "green && blue:" << std::endl;
    if(output.size())
    {
       std::cout<<boost::geometry::dsv(output[0])<<std::endl;
       std::cout<<boost::geometry::area(output[0])<<std::endl;
    }

    return 0;
}

回答1:


You can weed out the invalid geometries:

output.erase(
        std::remove_copy_if(output.begin(), output.end(), output.begin(), [](polygon_2d const&g) { return boost::geometry::is_valid(g); }),
        output.end());

Now, the result will be empty as expected.

See it Live On Coliru


It's interesting to me how "invalid" geometries would result in the first place. As you were probably aware that your polygons are very well chosen:

Let's zoom in a little:

Now, you're likely looking at some floating point accuracy issues, as the same experiment with long long points or boost multiprecision, e.g.:

typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<1024*128>> oopmh; // that's a lotta oomph
typedef boost::geometry::model::d2::point_xy<oopmh, boost::geometry::cs::cartesian> point_2d;

You will see that we get

green && blue:
(((2.4e+06, 530000), (-600000, 530000), (-600000, -530000), (2.4e+06, -530000), (2.4e+06, 530000)))
nan

So it looks very much like we just get a singular point of area. If you don't want this, then maybe you should just define an "epsilon" value of sorts, a threshold at which you stop considering an overlap an overlap.



来源:https://stackoverflow.com/questions/27335345/boost-geometry-intersection-does-not-output-correctly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!