【问题标题】:How to find out the intersection of two coplanar lines in C如何在C中找出两条共面线的交点
【发布时间】:2014-03-20 20:36:32
【问题描述】:

我有两条位于同一平面上的 3D 线。 line1 由一个点 (x1, y1, z1) 及其方向向量 (a1, b1, c1) 定义,而 line2 由一个点 (x2, y2, z2) 及其方向向量 (a2, b2, c2) 定义。那么两条线的参数方程是

x = x1 + a1*t;         x = x2 + a2*s;
y = y1 + b1*t;         y = y2 + b2*s;
z = z1 + c1*t;         z = z2 + c2*s;

如果两个方向向量都是非零的,我们可以通过将上面等式的右侧相等并从三个中的任何两个求解ts 来轻松找出相交节点的位置。但是,a1 b1 c1 a2 b2 c2 可能并非全部非零,因此我无法以相同的方式求解这些方程。我目前的想法是逐案处理这个问题,比如

case1: a1 = 0, others are nonzero
case2: a2 = 0, others are nonzero
case3: b1 = 0, others are nonzero
...

但是,总共有这么多案例,实施起来会变得混乱。有什么好的方法可以解决这个问题吗?有什么参考吗?非常感谢!

【问题讨论】:

  • 为什么不通过投影到平面上来表示线条?否则,您似乎正在尝试解决三个空间中的线交点。 (注意两个向量的叉积应该给你一个平面的法线向量,用它来做投影)
  • 听起来像矩阵的情况......
  • 等一下,给出了哪些信息来寻找交点的坐标?我的意思是,x1y1、...、c2 等等
  • @SteveCox 将线条投影到平面上是什么意思?你指的是哪架飞机?我知道两条线所在平面的法线向量。
  • @ThoAppelsin 这就是我唯一的...

标签: c line-intersection


【解决方案1】:

将其视为向量方程更为实际。点. 是标量积,A,n,B,m 是描述线的向量。点A 位于方向n 的第一行。方向已标准化:n.n=1m.m=1。交点C 是这样的:

 C=A+nt=B+ms

其中ts 是要计算的标量参数。

因此(.n):

A.n+ t=B.n+m.n s
t= (B-A).n+m.n s

和(.m):

 A.m+n.m t=B.m+ s
 A.m+n.m (B-A).n+(m.n)^2 s=B.m+ s
 n.m(B-A).n+(A-B).m=(1-(m.n)^2).s

由于 n.n=m.m=1 且 n 和 m 没有对齐,所以 (m.n)^2

 s=[n.m(B-A).n+(A-B).m]/[1-(m.n)^2]
 t= (B-A).n+m.n s

【讨论】:

    【解决方案2】:

    你可以用一个线性系统来解决这个问题:

    | 1 0 0 -a1   0 | | x |   | x1 |
    | 0 1 0 -b1   0 | | y |   | y1 |
    | 0 0 1 -c1   0 | | z | = | z1 |
    | 1 0 0   0 -a2 | | s |   | x2 |
    | 0 1 0   0 -b2 | | t |   | y2 |
    | 0 0 1   0 -c2 |         | z2 |
    

    x y z 是交点,s t 是向量的系数。这解决了@francis 编写的相同方程,其优点是它还获得了在您的数据不完美的情况下最小化错误的解决方案。

    这个方程通常表示为Ax=b,可以通过x = A^(-1) * b来求解,其中A^(-1)A的伪逆。所有的线性代数库都实现了一些函数来解决这样的系统,所以不用担心。

    【讨论】:

    • 很好的答案!非常简单,绝对解决了我的问题。现在我确定这两条线相互交叉,如果它们是平行的呢?需要检查这里的矩阵A是否秩亏?
    • 如果线是平行的(向量(abc)_1(abc)_2 在比例上是相同的),矩阵A 将是秩不足的(它的秩为4 而不是5) .同样,如果您的数据嘈杂且向量不完全相同,A 将排名第 5,但您的解决方案将不可靠。为防止出现这些情况,请检查A 的条件数:获取其奇异值并将最大的值除以最小值。越高,越差。如果直线完全平行,则最小奇异值为 0。
    • 当然,你也可以用点积来检查向量之间的角度,这样可能更容易。
    • 我明白了。点积似乎更容易。所以在形成这个线性系统之前,最好先检查两条线是否平行,保证算法稳定。
    【解决方案3】:

    记住计算永远不会精确可能很重要,常数和计算中的微小偏差可能会使您的线不完全相交。

    因此,让我们解决一个更一般的问题 - 找到线中对应点之间的距离最小的 ts 的值。这显然是微积分的一项任务,而且很容易(因为线性函数是微积分中最简单的函数)。

    所以要点是

    [xyz1]+[abc1]*t
    and
    [xyz2]+[abc2]*s
    

    (这里[xyz1]是一个3向量[x1, y1, z1]等等)

    它们之间的距离(平方):

    ([abc1]*t - [abc2]*s + [xyz1]-[xyz2])^2
    

    (这里 ^2 是 3 向量与自身的标量积)

    让我们找到这个关于t的导数:

    [abc1] * ([abc1]*t - [abc2]*s + [xyz1]-[xyz2])    (multiplied by 2, but this doesn't matter)
    

    (这里第一个* 是标量积,其他*s 是向量和数字之间的正则乘积)

    导数应在最小值处为零:

    [abc1] * ([abc1]*t - [abc2]*s + [xyz1]-[xyz2]) = 0
    

    让我们也使用关于s 的导数 - 我们也希望它为零。

     [abc1]*[abc1]*t - [abc1]*[abc2]*s = -[abc1]*([xyz1]-[xyz2])
    -[abc2]*[abc1]*t + [abc2]*[abc2]*s =  [abc2]*([xyz1]-[xyz2])
    

    从这里,我们找到ts

    那么,我们来找出这两个ts对应的点。如果所有计算都是理想的,那么这些点就会重合。但是,此时您实际上可以保证得到一些小的偏差,因此将这些点作为您的结果(两条线的交点)。

    最好取这些点的平均值,使结果对称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-29
      • 2011-10-25
      • 2014-01-07
      • 2020-03-25
      相关资源
      最近更新 更多