如何测试一个点是否在二维整数坐标中的凸多边形内部?
多边形以 Vector2I 对象列表的形式给出(二维、整数坐标)。 如何测试给定点是否在内部? 我在网上找到的所有实现都因一些微不足道的反例而失败。 编写正确的实现似乎确实很难。 语言并不重要,因为我会自己移植。
The polygon is given as a list of Vector2I objects (2 dimensional, integer coordinates). How can i test if a given point is inside? All implementations i found on the web fail for some trivial counter-example. It really seems to be hard to write a correct implementation. The language does not matter as i will port it myself.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
如果它是凸的,检查它的一个简单方法是该点位于所有线段的同一侧(如果以相同的顺序遍历)。
您可以使用点积轻松检查这一点(因为它与线段和点之间形成的角度的余弦成正比,如果我们用边缘的法线计算它,那些具有正号的将位于右侧,并且左边有负号的)。
这是 Python 中的代码:
If it is convex, a trivial way to check it is that the point is laying on the same side of all the segments (if traversed in the same order).
You can check that easily with the dot product (as it is proportional to the cosine of the angle formed between the segment and the point, if we calculate it with the normal of the edge, those with positive sign would lay on the right side and those with negative sign on the left side).
Here is the code in Python:
如果多边形是凸多边形,则在 C# 中,以下代码实现“测试是否总是在同一侧"方法,并且最多运行 O(n 个多边形点):
If the polygon is convex, then in C#, the following implements the "test if always on same side" method, and runs at most at O(n of polygon points):
光线投射或缠绕方法是解决此问题最常见的方法。 有关详细信息,请参阅维基百科文章。
另外,请查看此页面以获取详细记录溶液C.
The Ray Casting or Winding methods are the most common for this problem. See the Wikipedia article for details.
Also, Check out this page for a well-documented solution in C.
openCV 中的 pointPolygonTest 函数“确定点是否在轮廓内部、外部或位于边缘上”:
http://docs.opencv.org/modules/imgproc /doc/structural_analysis_and_shape_descriptors.html?highlight=pointpolygontest#pointpolygontest
The pointPolygonTest function in openCV " determines whether the point is inside a contour, outside, or lies on an edge":
http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=pointpolygontest#pointpolygontest
fortran 的答案几乎对我有用,除了我发现我必须翻译多边形,以便您正在测试的点与原点相同。 这是我为实现此目的而编写的 JavaScript:
fortran's answer almost worked for me except I found I had to translate the polygon so that the point you're testing is the same as the origin. Here is the JavaScript that I wrote to make this work:
我所知道的就是这样的。
您在多边形外部的某处选择一个点,它可能远离几何图形。
然后从这一点画一条线。 我的意思是你用这两点创建一个直线方程。
然后对于该多边形中的每条线,检查它们是否相交。
它们相交线数的总和可以告诉你它是否在内部。
如果是奇数:在里面
如果是偶数:在外面
the way i know is something like that.
you pick a point somewhere outside the polygon it may be far away from the geometry.
then you draw a line from this point. i mean you create a line equation with these two points.
then for every line in this polygon, you check if they intersect.
them sum of number of intersected lines give you it is inside or not.
if it is odd : inside
if it is even : outside
您必须检查要测试的点是否保持其相对于凸多边形的所有线段的方向。 如果是的话,它就在里面。 要对每个线段执行此操作,请检查线段向量 AB 和点向量 AP 的行列式是否保留其符号。 如果行列式为零,则该点位于线段上。
为了在 C# 代码中公开这一点,
行列式微积分,
You have to check that the point to test maintains it's orientation relative to all segments of the convex polygon. If so, it's inside. To do this for each segment check if the determinant of the segment vector say AB and the point's vector say AP preserves it's sign. If the determinant is zero than the point is on the segment.
To expose this in C# code,
The determinant calculus,
或者从写这本书的人那里看到 - 几何页面
具体< a href="http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/" rel="nofollow noreferrer">此页面,他讨论了为什么缠绕规则通常比射线更好穿越。
编辑 - 抱歉,这不是 Jospeh O'Rourke 写了这本出色的书 < a href="http://maven.smith.edu/~orourke/books/compgeom.html" rel="nofollow noreferrer">C 语言计算几何,作者是 Paul Bourke,但仍然是一个非常非常好的资源几何算法。
Or from the man that wrote the book see - geometry page
Specifically this page, he discusses why winding rule is generally better than ray crossing.
edit - Sorry this isn't Jospeh O'Rourke who wrote the excellent book Computational Geometry in C, it's Paul Bourke but still a very very good source of geometry algorithms.
这是我在项目中使用的版本。 它非常优雅和简洁。 适用于各种多边形。
http://www.eecs.umich.edu/courses/ eecs380/HANDOUTS/PROJ2/InsidePoly.html
以下代码由 Randolph Franklin 编写,对于内部点返回 1,对于外部点返回 0。
Here is the version I use in my project. It's very elegant and concise. Works for every kind of polygons.
http://www.eecs.umich.edu/courses/eecs380/HANDOUTS/PROJ2/InsidePoly.html
The following code is by Randolph Franklin, it returns 1 for interior points and 0 for exterior points.