我有一个小测试应用程序,用几个矩形与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);
}
我必须做错事,因为我希望结果类似于(35 30, 35 40, 25 40, 25 30, 35 30)
,但我得到包含像50 0
之类的点的10点长多边形,而平行矩形的交点应始终是4 +的矩形1点和50 0
位于边缘,所以它根本不应该在交叉点。如果我将它放入SVG,矩形似乎就像我期望的那样。
有什么不对?如果是boost::geometry
中的错误,我该如何确定它? (我目前正在使用1.48。)如果它是一个bug,有没有办法解决这个问题?
答案 0 :(得分:2)
polygon类具有以下模板参数:
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 {...}
如您所见,第二个模板参数默认为true。这意味着定义多边形的点被认为是/应该按顺时针顺序。
实际上这是你的问题。
如果您查看几何形状的WKT形式,则按逆时针顺序编写点。
所以你应该:
typedef boost::geometry::model::polygon<point,false> polygon;
或以顺时针顺序写入WKT字符串中的点。即:
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);
有了这个,结果将如你所料。
作为个人评论,如果read_wkt在阅读时强制执行正确的方向,那将是一件好事......
答案 1 :(得分:2)
我同意ds27680的答案。
第三个选项是在read_wkt之后调用boost :: geometry :: correct(几何),如果不确定方向,则鼓励用户这样做。
read_wkt确实没有强制执行正确的方向。原因是正确的函数需要区域计算,如果用户知道多边形的顺序正确(通常 已知),则可以保存区域计算。