1

给定一个向量 V = (x, y, z),我如何找到与 V 组成一个轴的 2 个向量?换句话说,其中一个垂直并位于同一平面内,另一个垂直于这两个向量。

我需要这个在 OpenGL 中实现一个不错的相机管理器。

4

2 回答 2

0

这个问题对于 StackOverFlow 来说确实是题外话,但我有一点时间。您要求形成正交向量的三元组,其中两个与给定向量正交。最简单的方法是使用 QR 分解。

我将在 MATLAB 中进行,它可以很好地处理线性代数。从任意列向量 v 开始。

v = [1 2 3]'
v =

     1
     2
     3

该数组一列的 QR 分解只产生矩阵 Q 和 R。我们只需要 Q。

[Q,R] = qr(v);

Q 的列为您提供所需的内容。

Q =

  -0.267261241912424   -0.534522483824849   -0.801783725737273
  -0.534522483824849    0.774541920588438   -0.338187119117343
  -0.801783725737273   -0.338187119117343    0.492719321323986

看到第一列只是 v,缩放为“单位”向量。如果您不喜欢所产生的方向,我们也可以在一组轴上任意乘以 -1。该矩阵的第二列和第三列是与给定向量正交的单位向量。

当然,这不是您可能完成的唯一方法。例如,可以选择任意两个其他随机向量,然后使用 Gram-Schmidt 正交化三个向量的集合。这是一个有效的方案,只要随机机会在您开始时没有产生一些线性相关集的向量。因此,该算法有可能失败,尽管极不可能。

另一种方案实际上只使用了一对叉积。因此,给定一些向量 v1:

  1. 随机选择 v2。

  2. 使用叉积,设置 v3=cross(v1,v2)。如果向量 v3 的范数为零,则返回步骤 1,因为这意味着向量 v1 和 v2 是共线的。

  3. 设置 v2 = 交叉(v1,v3)。

这个算法很简单,它确实与 Gram-Schmidt 正交化有一些相似之处,但编写起来相当简单。您需要小心第 2 步中的测试,因为测试一个数字是否正好为零并不是一个好主意。您可能还希望在计算向量时缩放向量以具有单位范数,因为这将解决一些数值问题。

最后,我仍然更喜欢使用 QR 分解,因为它很简单,不需要对“零”进行测试,因此不需要明确的容差。

于 2012-12-17T12:18:24.523 回答
0

只给你一个向量,你可以找到无数个垂直于它的向量。特别是这组向量形成了一个平面,您的给定向量垂直于该平面。

给定一些与第一个向量不共线的向量,您可以通过应用Gram-Schmidt 正交化来找到垂直(=正交)向量。让你的第一个向量是↑v,并且↑u是一些向量,所以 ↑u =/= l ↑v,然后是垂直的 ↑u_ = ↑u - ↑v ( ↑u · ↑v)

于 2012-12-17T01:12:39.090 回答