如何在 boost::geometry 中找到 2 个多边形的接触长度

How do i find the touching length of 2 polygons in boost::geometry?

本文关键字:多边形 接触 boost geometry      更新时间:2023-10-16

我在 boost::geometry 中有许多多边形,并希望从一个与第一个多边形具有最长公共边界的多边形中找到特定的邻居。多边形完全相互接触,因此boost::geometry::disjoint返回 false,但以下代码始终返回周长 0:

typedef boost::geometry::model::d2::point_xy<double>      boost_pnt;
typedef boost::geometry::model::polygon<boost_pnt>        boost_poly;
boost_poly otherPol = ...;
boost_poly thisPol  = ...;
if(! boost::geometry::intersection(thisPol, otherPol, out))
    return -1;
float perimeter = 0;
BOOST_FOREACH(boost_poly const& p, out)
{
    perimeter += boost::geometry::perimeter(p);
}
return perimeter;

如何找到共同的"边框",即两个多边形的接触长度?

我不是数学家,我不知道 boost::geometry 库,所以我应该试一试。 :-)

您需要将多边形 1 中的每个线段与多边形 2 中的每个线段进行比较。 所以在每个比较中,我们有两个线段,A 和 B

首先,我会比较两条线段的单位向量,如果它们相等或完全相反,则线是平行的。

如果线是平行的,我会取由 A 的一个点和 B 的一个点定义的线段(在这两种情况下哪个都无关紧要),并计算其单位向量。 如果该单位向量等于(或与上面的单位向量完全相反),则线段位于同一无限线上。

如果是这种情况,我们可以很容易地找到线段的哪些端点(如果有的话)位于另一个线段内。 即:如果 A.point1 向上且位于 B.point1 的左侧,而 B.point2 向上且位于 A.point1 的左侧,则 A.point1 位于线段 B 上(有助于绘制它。

请注意,其中一条线段可能完全位于另一条线段内 - 因此,如果 A 完全在 B 内,则 B 的两个端点都不会位于 A 内。

在 A 完全位于 B 内的情况下,这些段的共享边界当然是 A 的长度。

否则,求出 A 中的点和 B 中的点之间的最大长度,并从 A 和 B 的长度之和中减去该长度。

boost::geometrytry中的任何功能都有帮助,你应该使用! :-)

(请注意,我已经说了很多"等于",我们当然会处理浮点运算,所以相等是一个稍微灵活的术语。

我相信在

多边形接触但不重叠的情况下,操作geometry::intersection会在out中生成一个空容器,尽管仍然会返回true。这本质上是触摸的定义:没有室内的交集。

由于Boost.Geometry适用于内饰,因此您无法从中获得更多收益。

您真正想要的是将您的多边形视为库 CGAL 定义为 Nef 多边形的内容。CGAL 提供了一个 API,允许您获取一个 Nef 多边形作为两个 Nef 多边形的交集。如果操作数接触,结果将是多段线。

但不要屏住呼吸,Nef 操作速度较慢,API 比 Boost.Geometry 更复杂;通过自己实现该功能,您可能会获得更好的结果。