简体   繁体   English

Boost :: Geometry相交无法正常工作

[英]Boost::Geometry intersection not working as expected

I have a little test application to intersect a few rectangles with boost::geometry. 我有一个小测试应用程序,用boost :: geometry相交一些矩形。

typedef boost::geometry::model::point
<
double, 2, boost::geometry::cs::cartesian
> point;

typedef boost::geometry::model::polygon<point > polygon;

polygon Intersect(polygon p1, polygon p2) {
    std::vector < polygon > result;
    boost::geometry::intersection(p1, p2, result);
    return result.front();
}

polygon IntersectionTest() {
    polygon one, two, three, four;

    boost::geometry::read_wkt("POLYGON((35 25, 35 35, 15 35, 15 25, 35 25))", one);
    boost::geometry::read_wkt("POLYGON((45 30, 45 50, 25 50, 25 30, 45 30))", two);
    boost::geometry::read_wkt("POLYGON((50  0, 50 40, 10 40, 10  0, 50  0))", three);
    boost::geometry::read_wkt("POLYGON((40 20, 40 60,  0 60,  0 20, 40 20))", four);

    return Intersect(Intersect(Intersect(one, two), three), four);
}

I must do something wrong, because I expect the result to be something like (35 30, 35 40, 25 40, 25 30, 35 30) yet I get 10 points long polygons containing points like 50 0 while intersections of parallel rectangles should always be rectangles with 4+1 points and 50 0 is at the edge so it shouldn't be in the intersection at all. 我必须做错什么,因为我希望结果是类似(35 30, 35 40, 25 40, 25 30, 35 30) 30,35 40,25 40,25 30,35 (35 30, 35 40, 25 40, 25 30, 35 30)但是我得到了10个点长的多边形,其中包含像50 0点,而平行矩形的交点应该总是是具有4 + 1点的矩形,并且50 0在边缘,所以它根本不应该在相交处。 If I put it into an SVG , the rectangles seems to be as I expect them. 如果将其放入SVG中 ,则矩形似乎与我期望的一样。

What can be wrong? 有什么事吗 If it is a bug in boost::geometry how can I make sure it is? 如果是boost::geometry的错误,如何确定呢? (I'm currently using 1.48.) If it is a bug is there a way to circumvent the problem? (我当前使用的是1.48。)如果存在错误,是否可以解决该问题?

The polygon class has the following template parameters: 多边形类具有以下模板参数:

template
<
    typename Point,
    bool ClockWise = true,
    bool Closed = true,
    template<typename, typename> class PointList = std::vector,
    template<typename, typename> class RingList = std::vector,
    template<typename> class PointAlloc = std::allocator,
    template<typename> class RingAlloc = std::allocator
>
class polygon {...}

As you see the second template parameter defaults to true. 如您所见,第二个模板参数默认为true。 That means that the points that define the polygon are considered to be / should be in clockwise order. 这意味着将定义多边形的点视为/应该按顺时针顺序排列。

This is your problem actually. 这实际上是您的问题。

If you look at your WKT form of the geometries you wrote the points in counterclockwise order. 如果您查看几何的WKT形式,则会以逆时针顺序写入点。

So you should either: 因此,您应该:

typedef boost::geometry::model::polygon<point,false> polygon;

Or write the points in the WKT string in clockwise order. 或按顺时针顺序在WKT字符串中写入点。 Ie: 即:

boost::geometry::read_wkt("POLYGON((35 25, 15 25, 15 35, 35 35, 35 25))", one);
boost::geometry::read_wkt("POLYGON((45 30, 25 30, 25 50, 45 50, 45 30))", two);

With this, the result will be as you expected it. 这样,结果将达到您的预期。

As a personal comment it would be probably be a nice thing if read_wkt would enforce the correct direction on reading... 作为个人评论,如果read_wkt可以在阅读时强制执行正确的方向,那可能是一件好事。

I agree with the answer of ds27680. 我同意ds27680的答案。

A third option is to call boost::geometry::correct(a geometry) after read_wkt, and users are encouraged to do this, if not sure about the orientation. 第三种选择是在read_wkt之后调用boost :: geometry :: correct(a geometry),如果不确定方向,建议用户这样做。

read_wkt does indeed not enforce the correct orientation. read_wkt确实没有强制执行正确的方向。 The reason is that the correct function requires an area computation, which can be saved if users know the polygon is in the right order (usually it is known). 原因是正确的函数需要进行面积计算,如果用户知道多边形的顺序正确(通常已知的),则可以将其保存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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