Algorithm 求点的顺序以形成四边形
在给的时候,我遇到了,检查平行四边形,然后是直角。这是可行的,但前提是输入的点按一定顺序排列。也就是说,P1和P3必须彼此“相反”,而不是相邻 所以,问题来了。如果输入的四个点可以是任意顺序,您如何对它们进行排序,使它们以“正确”的顺序形成四边形 我能想到的最简单的方法是:Algorithm 求点的顺序以形成四边形,algorithm,geometry,Algorithm,Geometry,在给的时候,我遇到了,检查平行四边形,然后是直角。这是可行的,但前提是输入的点按一定顺序排列。也就是说,P1和P3必须彼此“相反”,而不是相邻 所以,问题来了。如果输入的四个点可以是任意顺序,您如何对它们进行排序,使它们以“正确”的顺序形成四边形 我能想到的最简单的方法是: for each valid permutation of points[]{ // see below for "valid" generate line segment for: points[0
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
),所以我可以保持第一点“固定”。另外,我想我可以通过只考虑每个排列点的0
和2
中的点来减少它,因为其他两个点的顺序并不重要。例如,如果0123
是多边形,0321
也是多边形,因为它生成相同的线段
这使我只需检查三种基本排列:
[0,1,2,3]
[0,1,3,2]
[0,2,1,3]
我想不出任何其他的方法来做到这一点,但我似乎错过了一些东西。有更好的方法吗?方形问题的答案很好,但如果我必须进行额外(最多)18次检查以验证点的顺序是否正确,则仅使用角间距离会更快。执行以下操作是否会更简单:
0、1
和2
是否跨越三角形(如果它们是共线的,则四边形也退化)否则,您应该正好有一个相交案例。您在那里找到了相反的顶点。实现一个名为isParallelAndEqual(p0、p1、q0、q1)的方法。这将检查线p1-p1和q0-q1是否平行且长度相等 给定a、b、c和d点,最终结果如下所示:
如果ParallelandEqual(a,b,c,d)|如果ParallelandEqual(a,c,b,d)你不能简单地检查以下所有内容,直到找到一个是正确的吗?(即,检查彼此相对的P1点) 对于方形变量,如果它们恰好是轴对齐的,您可以这样做:(即,相反的点是没有共同坐标的点) 每个排列有六个段到段的检查,因此总共有18个比较 您不需要检查所有的段:检查段
[0-2]
和[1-3]
(即两条对角线)是否相交就足够了。您需要检查线段是否相交,而不是线段所属的直线,即线段外的交点不计算在内
一旦您确定了起点“A”,您将得到六种可能的排列:
其中两个(A-B-D-C
和A-C-D-B
)是好的;剩下的四个是坏的。您只需两张支票即可获得一张好支票:
- 检查初始排列;如果它是好的,就保留它;否则
- 交换点1和2,并检查排列;如果它是好的,就保留它;否则
- 恢复到原始排列,交换点2和3,并保持该排列;这肯定是“好的”
3,0,1
是共线的(按那个顺序),它不会看到[1,3]
与[0,2]
相交吗?这是我在纸上提出的第一个反例,但我担心可能还有其他反例。我想我可以检查所有点组合的共线性,但是…@Geobits我认为这取决于交叉点检查。如果你使用叉积,找到边界案例不是很容易吗?(在[0,1]
中表示交叉点,所以0或1表示边界情况?)。对于叉积,如果使用浮点数学,必须非常小心。有效/退化四边形之间的差异可能非常小,而“精确为零”的效果不太好。现在我想,你的第一点最有意义。然而,第二种方法拒绝旋转的正方形。轴对齐方法是我想到的第一件事,但它确实限制了它的实用性。然而,+1。我不知道我的大脑是怎么跳过这个事实的,我可以跑三次方程式。当然,这实际上只适用于正方形/平行四边形问题,而不是一般的四边形。这是有意义的。两次排列检查,每次一次交叉检查。我认为它不可能比这简单得多,注意ABDC=ACDB,ABCD=ADCB和ACBD=ADBC。加上第四条线(第四点和第一点之间的线),你应该会看到它。@Dukeling Right,我故意跳过了方向对称(顺时针和逆时针),以说服自己该图涵盖了所有六种可能性。
[0, 3] and [1, 2]
[1, 3] and [0, 2]
[2, 3] and [0, 1]
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