8

计算垂直于第三个向量(X)并且彼此垂直的两个向量的最佳(最快)方法是什么?

这就是我现在计算这些向量的方式:

// HELPER - unit vector that is NOT parallel to X
x_axis = normalize(X);
y_axis = crossProduct(x_axis, HELPER);
z_axis = crossProduct(x_axis, y_axis);

我知道有无数种解决方案,我不在乎哪一个是我的解决方案。

这个问题的背后是什么:我需要构造变换矩阵,我知道 X 轴(矩阵中的第一列)应该指向哪个方向。我需要计算 Y 轴和 Z 轴(第二列和第三列)。众所周知,所有轴必须相互垂直。

4

5 回答 5

6

我做了什么,前提是X<>0或者Y<>0

  1. A = [-Y, X, 0]
  2. B = [-X*Z, -Y*Z, X*X+Y*Y]

然后对向量进行归一化。

[ X,Y,Z]·[-Y,X,0] = -X*Y+Y*X = 0
[ X,Y,Z]·[-X*Z,-Y*Z,X*X+Y*Y] = -X*X*Z-Y*Y*Z+Z*(X*X+Y*Y) = 0
[-Y,X,0]·[-X*Z,-Y*Z,X*X+Y*Y] = Y*X*Z+X*Y*Z = 0

这称为向量的零空间。

如果X=0Y=0那么A=[1,0,0]B=[0,1,0]

于 2012-05-22T14:04:14.923 回答
3

这是做到这一点的方法。
这也可能是唯一的方法。任何其他方式在数学上都是等效的。
通过打开 crossProduct 计算并确保您不会多次执行相同的乘法运算,可以节省几个周期,但这对于微优化领域来说真的很遥远。

您应该注意的一件事当然是 HELPER 向量。它不仅必须与 X 不平行,而且它与 X 非常不平行也是一个好主意。如果 X 和 HELPER 甚至有点平行,那么您的浮点计算将不稳定且不准确. 你可以测试看看如果 X 和 HELPER 的点积是 0.9999 会发生什么。

于 2012-05-22T12:36:51.690 回答
3

有一种方法可以找到一个好的 HELPER(真的 - 它已准备好成为您的 y_axis)。

让我们 X = (ax, ay, az)。选择 2 个量级较大的元素,交换它们,并取反其中一个。将第三个元素设置为零(幅度最小)。这个向量垂直于 X。

例子:

if (ax <= ay) and (ax <= az) then HELPER = (0, -az, ay) (或 (0, az, -ay))

X*HELPER = 0*0 - ay*az + az*ay = 0

如果 (ay <= ax) 和 (ay <= az) 那么 HELPER = (az, 0, -ay)

于 2012-05-22T13:15:25.600 回答
1

对于一个好的 HELPER 向量:找到绝对值最小的 X 坐标,并使用该坐标轴:

absX = abs(X.x); absY = abs(X.y); absZ = abs(X.z);
if(absX < absY) {
  if(absZ < absX)
    HELPER = vector(0,0,1);
  else // absX <= absZ
    HELPER = vector(1,0,0);
} else { // absY <= absX
  if(absZ < absY)
    HELPER = vector(0,0,1);
  else // absY <= absZ
    HELPER = vector(0,1,0);
}

注意:这实际上与@MBo 的答案非常相似:取坐标轴最小的叉积相当于将最小坐标设置为零,交换较大的两个,然后取反。

于 2012-05-22T18:17:23.740 回答
0

我认为单位向量中所有元素的最小最大幅度总是大于 0.577,所以你可以摆脱这个:

-> 通过查找幅度大于 0.5 的任何元素,将找到与 3D 向量的垂直向量到 2D 向量的问题减少,然后忽略不同的元素(在其位置使用 0)并将垂直线应用于 2D 向量其余元素中的公式(对于 2D x-axis=(ax,ay) -> y-axis=(-ay,ax))

let x-axis be represented by (ax,ay,az)

if (abs(ay) > 0.5) {
  y-axis = normalize((-ay,ax,0))
} else if (abs(az) > 0.5) {
  y-axis = normalize((0,-az,ay))
} else if (abs(ax) > 0.5) {
  y-axis = normalize((az,0,-ax))
} else {
  error("Impossible unit vector")
}
于 2012-09-02T03:00:38.210 回答