0

我想用boost::geometry确定点是否在多边形内。

我使用函数boost::geometry::within和 typeboost::geometry::linear_ring<boost::geometry::point_2d>来指定轮廓。

如果我不需要考虑轮廓的方向,一切都可以正常工作。
但就我而言,我想说明方向。我的意思是,如果特定轮廓的内部区域被认为受其边界限制并且是有限的,那么倒置轮廓的内部区域应该是无限的 - 与初始轮廓区域的互补。

是否可以在within功能中考虑轮廓的方向?

可以用以下代码表示:

// Create contour which defines square
boost::geometry::linear_ring<boost::geometry::point_2d> contour;
contour.push_back(boost::geometry::point_2d(4, 2));
contour.push_back(boost::geometry::point_2d(2, 2));
contour.push_back(boost::geometry::point_2d(2, 4));
contour.push_back(boost::geometry::point_2d(4, 4));
contour.push_back(boost::geometry::point_2d(4, 2));

// Create contour which defines square with opposite direction.
boost::geometry::linear_ring<boost::geometry::point_2d> contourInverted = contour;
std::reverse(contourInverted.begin(), contourInverted.end());

// Specify point inside square
boost::geometry::point_2d testPoint(3, 3);

// Perform tests
bool ret1 = boost::geometry::within(testPoint, contour);
bool ret2 = boost::geometry::within(testPoint, contourInverted);

上面的代码执行后ret1ret2都是true. 但我会的ret1 != ret2

一般来说,我需要在ret1 != ret2任何时候获得功能testPoint(当点恰好在边界上或多边形退化等时,我不考虑边界情况......)

我尝试了不同的策略来传递给boost::geometry::within,但我没有得到我需要的东西。

似乎我需要或类似的功能在 中的某处实现boost::geometry,因为inside的文档具有带孔的多边形示例。但我还没有意识到如何将它用于我的案例。

还有一个非常简单的解决方法。我只需要编写一个代码来确定轮廓的方向。然后我只是within根据轮廓方向否定或不否定函数的结果。但是如果boost::geometry已经实现了,我不想复制它。

4

2 回答 2

2

AFAIK,Boost.Geometry 和 Boost.Polygon 都不适用于您定义的“无限”区域。他们确实使用带有孔的多边形,甚至是一组这样的多边形。

您可能会考虑添加一个大矩形来限制您的宇宙。然后您可以将倒置轮廓定义为此类矩形中的孔。

顺便说一句,在许多情况下,可以避免将框转换为轮廓。Boost.Geometry 提供了一个适配器“box_view”,它允许像使用(正向)轮廓一样使用框。

至于任意轮廓的方向,可能最简单的方法是计算其面积。另一方面,对于格式良好的环,方向在编译时是已知的,并且由元函数提供 traits::point_order,请参阅此处的详细信息

于 2013-11-16T06:01:50.140 回答
0

几点说明:

  • 在 Boost.Geometry 中没有bg::linear_ring<>,有bg::model::ring<>
  • bg::model::ring<>是 Boost.Geometry 中的模型,称为环,它是一种面几何,是一个没有孔的简单多边形。
  • Ring 与 OGC LinearRing 不同,它是一种面 (2d) 几何形状,并且具有方向。OGC LinearRing 是 1d 的,没有方向。
  • bg::model::ring<>可以通过传递第二个模板参数在编译时设置方向,请参阅this
  • area()反向区域(笛卡尔)几何的函数返回的值是负区域(不是无限的)。但并非所有函数都适用于反向几何,因为库通常认为它们是无效的。

在 Boost.Geometry 中,数据必须反映几何的编译时设置,在这种情况下,在编译时为环设置的方向。否则结果可能出乎意料。在您的情况下,返回相同的值。bg::correct()在将几何传递给其他函数之前,您可以调用以自动更正方向和闭合。你也可以打电话bg::is_valid()来检查你的几何是否一切正常。

因此,如果您想检查一个点是否与几何内部重叠,您可以调用within(pt, ring). 如果您想检查一个点是否在边界上或与外部重叠,那么!within(pt, ring)应该返回您需要的内容,这当然是显而易见的。

如果您想考虑边界,请检查一个点是否与内部或边界重叠,然后您可以使用covered_by(pt, ring),!disjoint(pt, ring)intersects(pt, ring)。显然,这种情况下的补码可能是!covered_by(pt, ring),disjoint(pt, ring)!intersects(pt, ring)

在 Pt/Ring 的情况下,内部使用相同的代码来检查所有这些空间关系,因此调用哪一个无关紧要。

于 2015-04-27T12:34:00.227 回答