计算在3D中垂直于第三矢量的两个矢量

时间:2012-05-22 12:31:44

标签: math vector 3d

计算垂直于第三个向量(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轴(第二和第三列)。众所周知,所有轴必须相互垂直。

5 个答案:

答案 0 :(得分:3)

这是做到这一点的方法 它也可能是唯一的方式。任何其他方式在数学上都是等价的 通过打开crossProduct计算并确保您不会多次执行相同的乘法,可以节省几个周期,但这实际上远远超出了微优化范围。

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

答案 1 :(得分:3)

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

  1. A = [-Y, X, 0]
  2. B = [-X*Z, -Y*Z, X*X+Y*Y]
  3. 然后将矢量标准化。

    [ 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
    

    这称为向量的 nullspace

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

答案 2 :(得分:2)

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

设X =(ax,ay,az)。选择2个具有更大幅度的元素,交换它们,并否定其中一个元素。设置为零第三个元素(幅度最小)。该向量垂直于X.

示例:

if(ax&lt; = ay)和(ax&lt; = az)然后HELPER =(0,-az,ay)(或(0,az,-ay))

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

if(ay&lt; = ax)和(ay&lt; = az)然后HELPER =(az,0,-ay)

答案 3 :(得分:0)

对于良好的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的答案:使用最小坐标轴的交叉产品相当于将最小坐标设置为零,交换较大的坐标,并取消一个。

答案 4 :(得分:0)

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

- &GT;通过查找幅度大于0.5的任何元素,然后忽略不同的元素(在其位置使用0)并将垂直应用于2D矢量公式,减少向3D矢量找到3D矢量的垂直矢量到2D矢量的问题。其余元素(对于2D x轴=(ax,ay) - &gt; y轴=( - 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")
}