平原上有4个坐标点。 你需要用一条线连接它们。线不能越过自己。
你的策略是什么?
见图片
我的第一个直觉是将点组织为"左上角","右上角","左下角" "右下角"并继续连接它们,使左上角到左下角,左下角到右下角,右下角到右上角,右上角连接到左上角。
这在大多数情况下有效,但并非全部。有更好的策略吗?
谢谢大家。
答案 0 :(得分:2)
取三个点并形成一个顺时针三角形(将面积计算为两边的叉积 - 如果为负,则交换两个顶点)。
取第四点并计算它与前者的每个(定向)侧形成的三角形的面积。当你找到一个负面区域时,在这一边插入新的顶点就完成了。
事实证明,你没有找到负面区域,这意味着第四个点位于三角形内部。您可以将它插入任何一侧。
if Area(P0, P1, P2) < 0
Swap(P0, P1)
if Area(P0, P1, P3) < 0
Solution: P0-P3-P1-P2
else if Area(P1, P2, P3) < 0
Solution: P1-P3-P2-P0
else if Area(P2, P0, P3) < 0
Solution: P2-P3-P0-P1
else
Solution: P0-P1-P2-P3
更新
您可以使用所谓的locus方法来考虑它。假设您已经形成并定向了一个三角形并希望插入第四个点。选择要插入的边缘,可以绘制插入不会导致插入的所有位置 双方交叉。
看到允许区域的形状,您会发现它是半平面与插入侧的联合,以及原始三角形。
三角形的三条支撑线将平面划分为7个区域。在任何区域内,您可以选择在侧面插入1,2或3种可能性(在图中,我们位于类型1的区域中)。
这种显而易见的方法向您展示您必须将第四点与三角形边(区域测试)进行比较,在最坏的情况下,您不能避免与三者进行比较。
边界的形状告诉您需要使用哪种方程式,并且区域数量暗示您将需要执行多少次测试。
答案 1 :(得分:0)
好吧,我还没有把它比作100%肯定,但我认为以下方法可行:
到目前为止,我还没有想出一个失败的例子,但也许这只是因为对我来说太晚了。 :)
快速说明:
A 点 B = ax * bx + ay * by [+ az * bz ...] = | A || <强>乙强> | COS(angle_between_A_and_B)
提高计算效率:
首先,由于点积只能给出0到180度的角度,因此可以通过检查哪个余弦更小或更负,来检查哪个角度更大。这避免了需要执行反余弦。
仍然需要你为每个幅度执行sqrt函数,因为点积给你| A || B | cos(角度),你必须除以| A || B |得到余弦。但是,通过一点启发式,我们也可以避免使用sqrt。 | A |和| B |必须始终是积极的。所以:
如果一个点积为负数而另一个为正数,那么 负点积必须具有负余弦,而另一个具有负余弦 一个正余弦,所以负一个是一个更大的角度。
如果它们都是正面的,那么你可以对点积进行平方,并且 然后除以平方的幅度(x ^ 2 + y ^ 2 [+ z ^ 2 ...]没有 sqrt)。较小的结果将是较小的余弦,因此角度较大。
如果点积为负数,则执行相同的操作 操作,但随后较大的结果将是较小的余弦,因此角度较大。