Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 我是否可以仅使用多边形点的子集来确定多边形的内部位置?_Algorithm_Graphics_Geometry - Fatal编程技术网

Algorithm 我是否可以仅使用多边形点的子集来确定多边形的内部位置?

Algorithm 我是否可以仅使用多边形点的子集来确定多边形的内部位置?,algorithm,graphics,geometry,Algorithm,Graphics,Geometry,我正试图用大量的点(n>100000)渲染多边形的子集。我决定将多边形的点放在二叉树中,这样我就可以快速找到视图框中的点并进行渲染 我想弄明白的问题是:如果我只得到多边形点的子集,我怎么知道多边形的内部在哪里?i、 e,我应该填充的区域?为了进一步解释我的问题,我在下面附上了一张图片: 对于上图,给定完整多边形的点子集(遍历二叉树后返回)。我是否可以确定多边形的哪一侧(A或B)是内部,并进行相应的填充 如果不可能,是否有更好的方法来存储或检索多边形,以便更好地找到多边形的内部?最简单的方法(通

我正试图用大量的点(n>100000)渲染多边形的子集。我决定将多边形的点放在二叉树中,这样我就可以快速找到视图框中的点并进行渲染

我想弄明白的问题是:如果我只得到多边形点的子集,我怎么知道多边形的内部在哪里?i、 e,我应该填充的区域?为了进一步解释我的问题,我在下面附上了一张图片:

对于上图,给定完整多边形的点子集(遍历二叉树后返回)。我是否可以确定多边形的哪一侧(A或B)是内部,并进行相应的填充

如果不可能,是否有更好的方法来存储或检索多边形,以便更好地找到多边形的内部?

最简单的方法(通常也是采用的方法)是在链接列表中连接多边形的顶点,并对其进行排列,以使后续多边形按逆时针顺序围绕多边形区域排列。这样,多边形的区域始终位于任何边的右侧


即使上面正方形的部分被覆盖,您仍然能够确定多边形的内部位置。排序本身可以在
O(n)
中完成,如果点的顺序不正确(很可能)。

您需要的是将多边形分割成如下部分:

  • 选择了一些内部点
    C
    (水上中心)

    该点必须位于多边形内部,如果放置在多边形的中心,则该点最好。您可以将其作为BBOX的中心,或对角线的中心(多边形周长的任意两个点之间的直线,彼此之间的距离足够远,就像点的一半)或两条对角线的交点,或作为所有点的平均值,甚至是随机获得的,或以您想要的方式获得

    然后检查它是否位于多边形内。但是,必须使用慢速方法(使用所有多边形点)完成此操作。幸运的是,这个点只需要计算一次(在多边形的创建/加载/初始化时)

    在错误的中心的情况下,只需使用不同的点生成它或稍微移动它,直到它的内部

  • 将多边形划分为多个部分

    在选定中心和任何多边形点之间使用对角线(灰线)。选择点,使截面具有大致相同的点数,并且对角线本身不得与任何多边形边相交。因此,如果你得到了
    m
    点,并且想要
    n
    节,则使用每个
    m-th
    点作为对角线。。。若相交,则使用附近的点,直到正确为止

    每个多边形也应只进行一次截面

  • 内部速度更快

    现在,要检测是否有任何点(洋红色)在内部,首先通过在所有对角线之间执行CW/CCW检查或使用
    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
    仍然是正确的

    这将告诉您该点位于哪个截面,所以现在请执行多边形内部检查,但只使用截面点和使用的对角线,而不是整个多边形

    现在,当你有两条最近的对角线CW
    D(i)
    和CCW
    D(j)
    时,只需测试由
    C
    D(i)
    D(j)
    之间的所有点构成的多边形

    正如您所看到的,截面越多,检查所需的点就越少(但对角线越多)

  • PS这张便条是给保罗的

    使用CW/CCW-ness的算法仅适用于凹多边形上的凸多边形。如图所示,存在假阴性:


    通常的方法是从给定点水平向左投影一条线,并找到该线相交的最近边。该边的方向告诉您该点是在多边形内部还是外部(根据Paul的建议施加路径方向)。如果没有遇到边缘,那么您当然在外部

    要实现这一点,您需要二叉树的每个单元引用通过该单元的每条边,即使其顶点位于单元外部。有时可能需要遍历多个单元以找到最近的相交边

    举例说明:

    在包含我们感兴趣的点的单元格内(见上面右侧的放大图),我们从该点向左侧投射一条线。在到达单元边界之前,它不会遇到任何边。所以我们必须穿过下一个单元,继续我们的路线。它撞击y方向为正的边;因此,我们得出结论,该点位于多边形之外

    请注意,单元可以保存位于单元边界之外的顶点的信息,以便引用穿过单元的每条边

    这种方法适用于任何复杂的多边形,只要它们不自相交,以及具有多个(未连接)轮廓的形状

    处理自交多边形:

    如果您希望遇到自交多边形,则无法再通过检查ne来判断您是在内部还是外部