如何检测一条线是否与另一个图形重合?

时间:2012-11-09 08:32:03

标签: algorithm visual-c++ geometry

我正在尝试制作一个程序来找到2点之间的最短路径。

我想到的是将起点连接到每个形状的所有顶点。这些点中的每一个都将连接到所有其他点 - 从而形成一种树。在圆形形状的情况下 - 直线将形成与圆或圆弧相切的点(因为这是围绕对象的最短路径)。然而,那些穿过其他物体的线被处理掉了。其余路径需要进行* A **搜索。

但是现在我如何让程序识别通过其他数字的线?我正在使用visual c ++,所以我可以通过将某些坐标传递给相应的函数(eg LineTo(21,23))来在客户区绘制形状。如何知道一条线何时进入另一个数字? enter image description here

2 个答案:

答案 0 :(得分:0)

直截了当的算法考虑到你到目前为止所做的事情:

  1. 对于每个形状存储数组(或列表)中的所有顶点,以便它们出现在形状上(顺时针或逆时针方向没有区别)。这允许您轻松迭代任何给定对象的边缘,因为在这种情况下边缘(P 1 ,P 2 (P 2 ,P 3 ,... (P N ,P 1 < / sub>)其中 N 是顶点数。
  2. 对于您要检查的每一行是否与任何对象发生碰撞都会迭代您所表示的所有边缘,如果您正在检查的行正在越过任何边缘 - 行与给定对象发生碰撞。
  3. 检查线与边的交叉是几何问题。如果我们检查的线的边界点是 P 1 =(x 1 ,y 1 和< strong> P 2 =(x 2 ,y 2 ),边缘的边界点 P 3 =(x 3 ,y 3 P 4 =(x 4 ,y 4 那么你应该解决线性系统:

      

    (x 2 - x 1 )y +(y 1 - y 2 ) x = x 1 y 2 - x 2 y 1

      (x 4 - x 3 )y +(y 3 - y 4 )x = x 3 y 4 - x 4 y 3

    获得(x,y)的值后,您应该检查它是否位于两条线上的边界点之间的部分(我们正在检查的线和边缘)。如果这是真的,你的线条会相互交叉。

    注意:您可以在检查碰撞时不迭代每个对象的边缘,而只是在行的路径中的那些对象上,来改善运行时间。这可以通过计算包含每个对象的最小矩形,并检查您的线是否通过矩形来完成,从而进一步检查该对象是否不进行检查。

答案 1 :(得分:0)

您可以区分两种情况:

线条正在通过另一条线进入数字。在这种情况下,最简单的方法是用它们的方程式表示你的线条(包括障碍物的边界)(它们看起来像a*x + b*y +c = 0)。然后决定两条线是否相交是一件非常简单的事情:

  • 当且仅当它们不平行时,两行ax + by + c = 0且dx + ey + f = 0相交,即iff a * eb * d!= 0

  • 然后你必须检查这两行的交点是否在你实际考虑的段内。交点具有坐标:

    • y =(cd - af)/(ae - db)
    • x =(bf - ec)/(ae - db)
  • 唯一剩下的任务是检查这些x和y是否属于该段(如果它们在定义段的区间内) 并且您为定义障碍物的所有段重复此操作。

如果你有圆圈,它会变得更加棘手(这就是为什么你通常只考虑多边形作为障碍物),但基本上它是相同的想法: - 你有一个线轴+ + c = 0和一个圆(x-a)^ 2 +(y-b)^ 2 = r ^ 2(中心圆(a,b)和半径r)。然后你必须确定它们是否相交,交叉点以及它是否属于你考虑的段。我会把这些计算留给你。

如果您对使用障碍物找到两点之间路径的不同方法感兴趣,可以使用其他算法,尽管这些算法不会为您提供最短路径,但只提供路径:

与您正在构建的可见性图表相比,这些算法的兴趣在于,这两种算法可以在任何维度上运行:如果要将算法升级到维度,则算法将具有更高的复杂度(需要更多找到路径的时间)然后这两个并不会产生最短的路径。