我们在二维平面上给出了4个点的坐标。如何找到一种连接它们形成四边形的顺序(如果可能的话)?
我们在二维平面上给出了4个点的坐标。如何找到一种连接它们形成四边形的顺序(如果可能的话)?
p_n
视为具有坐标 (x_n, y_n)
的点。x
值的点 p_1
。p_1
到其余每个点的3条线的 斜率。p_1
与具有最大斜率的点 p_2
连接。p_1
与具有最小斜率的点 p_3
连接。p_4
与 p_2
和 p_3
连接。Px = Ax + u (Bx - Ax) + v (Cx - Ax)
Py = Ay + u (By - Ay) + v (Cy - Ay)
(0, 0)
映射为A
,将(1, 0)
映射为B
,将(0, 1)
映射为C
。(这将三角形ABC放置在规范位置。)Dx = Ax + u (Bx - Ax) + v (Cx - Ax)
Dy = Ay + u (By - Ay) + v (Cy - Ay)
这将为您提供与 D
相应的 (u, v)
值。
然后,
if u < 0 => ABCD
else if v < 0 => BCAD
else => CABD
得到的四边形方向与三角形 ABC
相同。
编辑:正如评论中指出的那样,它只适用于特定情况,因此是一个糟糕的答案。
四边形可以通过找到4个点中距离最远的一对点来绘制。一旦找到这对点,就可以通过将剩余的两个点与每个点连接来绘制四边形。
编辑:这个回答已经被证明是错误的。
您可以使用任何凸包的著名算法的简化版本。Jarvis算法是比较容易实现的。如果凸包是一个三角形,那么四边形就是凸的。只需在边缘列表中的任意位置插入缺失的点即可。如果凸包是一条线(2个端点),只需按x或y坐标对所有点进行排序,以获得退化的四边形。(如果更接近水平(abs delta x > abs delta y),则使用x进行排序,否则使用y。)
寻找凸包算法。其中之一由两个步骤组成:在给定的顶点集上构建普通多边形(可能是凹的),然后删除“凹顶点”,使剩余的多边形变为凸多边形。
第一步是解决您问题的方案。
当然,这有点过度了。对于4个顶点,只需将它们按顺序设置(任意顺序),然后验证连接点1-2和3-4的线段是否相交;如果是,则交换点2和3;或者可能边缘2-3和1-4相交-然后交换点3和4。完成。
要验证线段AB和CD是否相交,请测试点A和B是否在线CD的两侧,以及点C和D是否在线AB的两侧。
要确定点K所在的线PQ的哪一侧,请计算PQ×PK向量积的Z部分:(xq-xp)(yk-yp)-(yq-yp)(xk-xp)
。该表达式在线的一侧为正,在另一侧为负(在线上为零)。
这里有一种简单的、非数学的方法来解决问题。我已经在几个例子上尝试过了,没有发现错误。如果您知道如何改进它,请告诉我:
就是这样。
注意:在选择前两个点时,有一些特殊情况:
通过使用一个函数来判断两条线段是否相交,可以很容易地解决这个问题。
给定点A、B、C、D,只有三种不同的连接顶点的顺序:ABCD、ABDC和ACBD(顶点A要么连接到顶点B,要么不连接。如果连接,则有两种方式来排序C和D。如果不连接,则A连接到C和D中的每一个,而且这些点都必须连接到B)。
如果四个点的排序产生了一个四边形,并且除了在角落处之外,没有任何边相交,那么就可以得到一个有效的排序过程:
If AB intersects with CD then return ACBD.
If AD intersects with BC then return ABDC.
Otherwise return ABCD.
这个方法的证明很简单:
如果您无法自行解决问题,则可以在网上找到确定两条线段是否相交的代码。