我在 3D 空间中有 2 个点,每个点有一个向量。我需要知道这两个向量是否彼此相交。还有交叉点(如果存在)。
我尝试搜索,但我的英语知识不足以进行这种搜索。如果有人有链接或解释,我将非常感激。
我相信你指的是线,而不是矢量。向量就像空间中的单个点,线是连续的点集。
首先,考虑您想要如何表示线条。您可能首先尝试的方法是使用
y = mx+b
。但这对于您来说可能不是最容易以编程方式完成的事情,并且它不能很好地扩展到 3D。
相反,您应该使用如图所示的线的矢量表示。
[x, y] = [m_x, m_y]*t + [b_x, b_y]
基本上这个方程的意思是,点 x 和 y 被定义为基点,我将其写为
[b_x, b_y]
,加上某个向量 [m_x, m_y]
的标量倍数。您可以将其视为斜率向量,并且它按某个数字 t
进行缩放。通过插入不同的 t
值,您可以得到 线上的每个点。
我们可以通过以下方式从
y = mx + b
进行转换:
b
是 y 轴截距。这是一个点 [0, b]
,这是我们的 [b_x, b_y]
术语。m
是斜率,是m_y/m_x
的比率。如果您有一个方程,其中 m=3
那么您就知道 y 的增长速度比 x 快 3 倍。这可以让我们 [m_x, m_y]
成为 [1, 3]
、[4, 12]
,或者其他任何东西,只要 m_y/m_x = m
。现在我们将有两个方程,每行一个。
(1) [x, y] = [m_x_1, m_y_1]*t + [b_x_1, b_y_1]
(2) [x, y] = [m_x_2, m_y_2]*s + [b_x_2, b_y_2]
如果我们将这两个方程设置为彼此相等,那么我们可以求解 s 和 t 来找出交点在哪里,或者是否存在交点。
[m_x_1, m_y_1]*t + [b_x_1, b_y_1] = [m_x_2, m_y_2]*s + [b_x_2, b_y_2]
接下来,我们可以将
m*s
和 m*t
项表示为矩阵乘法。在这个阶段,我将开始垂直绘制向量,而不是水平绘制。
|m_x_1, -m_x_2| * |s| = |b_x_2 - b_x_1|
|m_y_1, -m_y_2| |t| |b_y_2 - b_y_1|
现在我们有一个由以下矩阵方程表示的线性方程。在这种情况下,
[s, t]
是我们的x
,我们正在努力解决这个问题。该方程告诉我们,我们可以通过将 x
的矩阵逆乘以 A
来求解 b
。
Ax=b
x=A^-1b
您可以在此处阅读有关矩阵逆的内容。只需知道 2x2 矩阵可以按如下方式计算其逆矩阵:
|a, b|^-1 = 1/(ad - bc) * |d, -b|
|c, d| |-c, a|
现在请注意
(ad-bc)
术语。它是一个分母,如果它为零,则矩阵逆矩阵的答案未定义。 这意味着没有交点,对于我们的直线方程,没有交点看起来像这样:
0 = m_x_1 * -m_y_2 + m_x_2 * m_y_1
如果不为零,那么我们可以得出如下的
s, t
项:
[s, t] = 1/(m_x_1 * -m_y_2 + m_x_2 * m_y_1) * [(b_x_1 - b_x_2), (b_y_1, b_y_2)]
现在这些 s 和 t 项将是来自
(-Infinity, +Infinity)
的实数。如果你只关心射线相交,那么你可以扔掉一个并保留一个,我就拿s
。这个 s
为我们提供了在线 (1)
上发生相交的点。我们可以将其代入方程并得到交集。 [x, y]
这里就是你的十字路口。
[x, y] = [m_x_1, m_y_1]*t + [b_x_1, b_y_1]
我不相信我犯了任何错误,但尝试自己将其扩展到 3D,步骤是相同的!.
以向量方式,您想要求解参数
r
和 s
系统
P + r.U = Q + s.V
相当于
Px + r.Ux = Q.x + s.Vx
Py + r.Uy = Q.y + s.Vy
Pz + r.Uz = Q.z + s.Vz
(点
P
和 Q
,向量 U
和 V
)。
这是一个包含 2 个未知数的 3 个方程组,通常无解。兼容性条件可以写
|Ux Vx Px-Qx|
|Uy Vy Py-Qy| = 0
|Uz Vz Pz-Qz|
如果该条件成立*,您可以求解通过删除其中一个方程而获得的 2x2 系统。如果要将解限制为由点和向量定义的线段,请检查
r
和 s
属于 [0, 1]
。从 r
或 s
您可以计算交叉点的位置。
*由于浮点问题,条件可能不完全成立。讨论它应该有多接近 0 超出了本答案的范围。