如何将两种类型的点连接到没有相交的线?

时间:2013-09-27 01:04:14

标签: algorithm geometry

如何连接两组坐标中的点与没有相交的线相交的任何一条线?

我有两种类型的点(a1, a2, ..., an, b1, b2, ..., bn)及其(x,y)坐标。

a和点b中的每一个点必须一次用直线连接,这样任何一条线都不会相交。

如何做到这一点?

输入(type,x,y):

a x y b x y a x y b x y

输出(ax,ay,bx,by):

ax ay bx by ax ay bx, by

enter image description here

4 个答案:

答案 0 :(得分:4)

图论中的欧几里德二分匹配(EBM)问题(Google it)寻求匹配蓝点和红点,以便最小化所有边长的总和。可以使用Hungarian Algorithm来解决。要看到这是一个无交叉的图表,只需考虑你的“坏”和“好”的图片。 “良好”图片中边长的总和总是较小。 (这是a slightly more detailed argument。)

这是另一个提供更多细节的SO answer

这是an interesting article about how EBM is used on Android to track multi-touch

答案 1 :(得分:1)

我不确定如何证明它,但感觉正确的是必须始终存在至少一对点(ax1,ay1) - >(bx1,by1),它们定义了一条将空间细分为两个截然不同的一半。每个半部分具有相同数量的未配对a和b点。我不能想出一个不是这种情况的点布局。

找到此细分后,两个点将标记为已连接,并且两侧的两个半空格将再次处理。这将重复,直到两个半空间都包含零点。

查找细分对并非易事,但可以通过详尽的搜索来完成。希望有人会提出一种计算量较小的方法,但这应该可行。

答案 2 :(得分:1)

这是我认为很有前景的方法。创建红色和蓝色点(R1,B1),(R2,B2),...(Rn,Bn)的配对。然后浏览列表,并为每个(Rj,Bj)绘制一条直线Rj - Bj。如果这条线穿过已经绘制的任何其他线Ri-Bi,则通过用Ri-Bj和Rj-Bi替换它们来“交叉”这些线(实际上将你的“坏”图片改为你的“好”图片)。 / p>

您必须检查这些新线是否穿过任何其他现有线,在这种情况下,您重复执行相同的“交换”和“交叉检查”,直到没有更多的交叉线。然后你继续在(Rj,Bj)之后加入该对,依此类推,直到你完成。

my other answer所述,红色和蓝色点的配对使总边长最小化也将是无交叉的。在本答案中给出的方法中,请注意每次“非交叉”边缘时,都会减少所有边长的总和。该算法很可能不会达到具有最小边长总和的配对配置。但是,总边沿长度随着每次交换而减少的事实意味着算法将始终终止(即,您不会进入重复的边缘交换序列)。

答案 3 :(得分:0)

这里已经间接回答:How do you detect where two line segments intersect?

您可以轻松测试连接点的任意组合,并检查它们是否相交!