查找点的顺序以制作四边形

时间:2013-08-06 15:12:44

标签: algorithm geometry

在向an answer提供"Given four coordinates check whether it forms a square"的同时,我遇到了this answer,它检查了平行四边形,然后是直角。这是有效的,但只有当进入的点按特定顺序时才有效。即,P1和P3必须彼此“相对”,而不是相邻。

所以,问题。如果进入的四个点可以按任何顺序排列,那么如何对它们进行排序以使它们处于“正确”的顺序以制作四边形?

我能想到的最简单的事情是:

for each valid permutation of points[]{ // see below for "valid"
    generate line segment for:
        points[0] -> points[1]
        points[1] -> points[2]
        points[2] -> points[3]
        points[3] -> points[0]
    if any line segment crosses another // use cross product
        continue
    return permutation
}

我知道大多数排列都是简单的旋转(0123 == 1230),所以我可以保持第一个点“固定”。另外,我想我可以通过仅考虑每个排列点的02中的点来减少它,因为其他两个的顺序无关紧要。例如,如果0123是多边形,0321也是,因为它会生成相同的段。

这让我只有三种基本排列检查:

  • [0,1,2,3]
  • [0,1,3,2]
  • [0,2,1,3]

每个排列都有六个段到段的检查,因此总共进行了18次比较。

我想不出有任何其他办法可以做到这一点,但似乎我错过了一些东西。有一个更好的方法吗?对于方形问题给出的答案是好的,但是如果我必须进行额外的(最多)18次检查以验证点的顺序是否正确,那么使用角间距离会更快。

4 个答案:

答案 0 :(得分:2)

  

每个排列都有六个段到段的检查,因此总共进行了18次比较。

您无需检查所有细分:检查细分[0-2][1-3](即两条对角线)是否相交就足够了。您需要检查段是否相交,而不是段所属的行,即段之外的交叉点不计算。

修正起点"A"后,您最终会得到六种可能的排列:

enter image description here

其中两个(A-B-D-CA-C-D-B)很好;剩下的四个都不好。只用两张支票就可以得到一个好的:

  • 检查初始排列;如果它是好的,保持它;否则
  • 交换点1和2,并检查排列;如果它是好的,保持它;否则
  • 恢复原始排列,交换第2点和第3点,并保持排列;它一定是“好”。

答案 1 :(得分:1)

实现一个名为isParallelAndEqual(p0,p1,q0,q1)的方法。这将检查行p1-p1和q0-q1是否平行且长度相等。

给定a,b,c和d点,最终结果如下:

ifParallelAndEqual(a,b,c,d)|| ifParallelAndEqual(a,c,b,d)

答案 2 :(得分:1)

难道你不能简单地检查以下所有内容,直到找到一个是真的吗? (也就是说,检查P1对面的点)

P3 = P1 + (P2-P1) + (P4-P1)
P2 = P1 + (P3-P1) + (P4-P1)
P4 = P1 + (P2-P1) + (P3-P1)

对于方形变体,如果它们碰巧是轴对齐的,你可以这样做:(也就是说,相反的点是没有共同坐标的那个)

if (P1.x != P3.x && P1.y != P3.y)
  check P3 = P1 + (P2-P1) + (P4-P1)

if (P1.x != P2.x && P1.y != P2.y)
  check P2 = P1 + (P3-P1) + (P4-P1)

if (P1.x != P4.x && P1.y != P4.y)
  check P4 = P1 + (P2-P1) + (P3-P1)

otherwise return false

答案 3 :(得分:0)

执行以下操作会不会更简单:

  1. 检查点0, 12是否跨越三角形(如果它们是共线的,则四边形也会退化)
  2. 检查以下段以进行交叉:
  3. [0, 3] and [1, 2]
    [1, 3] and [0, 2]
    [2, 3] and [0, 1]
    

    如果它们都不相交,则四边形是非凸的。

    否则,您应该只有一个交叉的情况。你在那里找到了相反的顶点。