Algorithm 我是否可以仅使用多边形点的子集来确定多边形的内部位置?
我正试图用大量的点(n>100000)渲染多边形的子集。我决定将多边形的点放在二叉树中,这样我就可以快速找到视图框中的点并进行渲染 我想弄明白的问题是:如果我只得到多边形点的子集,我怎么知道多边形的内部在哪里?i、 e,我应该填充的区域?为了进一步解释我的问题,我在下面附上了一张图片: 对于上图,给定完整多边形的点子集(遍历二叉树后返回)。我是否可以确定多边形的哪一侧(A或B)是内部,并进行相应的填充 如果不可能,是否有更好的方法来存储或检索多边形,以便更好地找到多边形的内部?最简单的方法(通常也是采用的方法)是在链接列表中连接多边形的顶点,并对其进行排列,以使后续多边形按逆时针顺序围绕多边形区域排列。这样,多边形的区域始终位于任何边的右侧Algorithm 我是否可以仅使用多边形点的子集来确定多边形的内部位置?,algorithm,graphics,geometry,Algorithm,Graphics,Geometry,我正试图用大量的点(n>100000)渲染多边形的子集。我决定将多边形的点放在二叉树中,这样我就可以快速找到视图框中的点并进行渲染 我想弄明白的问题是:如果我只得到多边形点的子集,我怎么知道多边形的内部在哪里?i、 e,我应该填充的区域?为了进一步解释我的问题,我在下面附上了一张图片: 对于上图,给定完整多边形的点子集(遍历二叉树后返回)。我是否可以确定多边形的哪一侧(A或B)是内部,并进行相应的填充 如果不可能,是否有更好的方法来存储或检索多边形,以便更好地找到多边形的内部?最简单的方法(通
即使上面正方形的部分被覆盖,您仍然能够确定多边形的内部位置。排序本身可以在
O(n)
中完成,如果点的顺序不正确(很可能)。您需要的是将多边形分割成如下部分:
C
(水上中心)
该点必须位于多边形内部,如果放置在多边形的中心,则该点最好。您可以将其作为BBOX的中心,或对角线的中心(多边形周长的任意两个点之间的直线,彼此之间的距离足够远,就像点的一半)或两条对角线的交点,或作为所有点的平均值,甚至是随机获得的,或以您想要的方式获得
然后检查它是否位于多边形内。但是,必须使用慢速方法(使用所有多边形点)完成此操作。幸运的是,这个点只需要计算一次(在多边形的创建/加载/初始化时)
在错误的中心的情况下,只需使用不同的点生成它或稍微移动它,直到它的内部m
点,并且想要n
节,则使用每个m-th
点作为对角线。。。若相交,则使用附近的点,直到正确为止
每个多边形也应只进行一次截面atan2
(在这种情况下,每个对角线角度可以预先计算一次以加快过程)来检查它在哪个部分,找到两条对角线,即有问题的包络点:
所以找到一条对角线,它是指向点的,并且有最小的角度。。。还有一个是《特定常规武器公约》。如果“中心”点为C
,测试点为P
,对角线点为D(i)
,则
angle = acos(dot(P-C,D(i)-C)/(|P-C|*|D(i)-C|))
交叉点(p-C,D(i)-C)的z坐标将告诉您对角线/角度是顺时针还是逆时针。我认为您可以忽略acos
,因为没有它的非线性结果应该仍然是单调的,所以min,max
仍然是正确的
这将告诉您该点位于哪个截面,所以现在请执行多边形内部检查,但只使用截面点和使用的对角线,而不是整个多边形
现在,当你有两条最近的对角线CWD(i)
和CCWD(j)
时,只需测试由C
和D(i)
和D(j)
之间的所有点构成的多边形
正如您所看到的,截面越多,检查所需的点就越少(但对角线越多)通常的方法是从给定点水平向左投影一条线,并找到该线相交的最近边。该边的方向告诉您该点是在多边形内部还是外部(根据Paul的建议施加路径方向)。如果没有遇到边缘,那么您当然在外部 要实现这一点,您需要二叉树的每个单元引用通过该单元的每条边,即使其顶点位于单元外部。有时可能需要遍历多个单元以找到最近的相交边 举例说明: 在包含我们感兴趣的点的单元格内(见上面右侧的放大图),我们从该点向左侧投射一条线。在到达单元边界之前,它不会遇到任何边。所以我们必须穿过下一个单元,继续我们的路线。它撞击y方向为正的边;因此,我们得出结论,该点位于多边形之外 请注意,单元可以保存位于单元边界之外的顶点的信息,以便引用穿过单元的每条边 这种方法适用于任何复杂的多边形,只要它们不自相交,以及具有多个(未连接)轮廓的形状 处理自交多边形: 如果您希望遇到自交多边形,则无法再通过检查ne来判断您是在内部还是外部