Math 计算与3D中第三个向量垂直的两个向量

Math 计算与3D中第三个向量垂直的两个向量,math,vector,3d,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)且彼此垂直的向量的最佳(最快)方法是什么

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

// 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轴(第二列和第三列)。正如我们所知,所有轴必须相互垂直。

这是一种方法。
这可能也是唯一的方法。任何其他方法在数学上都是等价的。
通过打开叉积计算,并确保您不会多次执行相同的乘法,可能可以节省一些周期,但这真的离微观优化领域很远


当然,有一件事需要注意,那就是辅助向量。它不仅必须与X不平行,而且最好与X不平行。如果X和HELPER甚至有些平行,则浮点计算将不稳定且不准确。如果X和HELPER的点积类似于0.9999,您可以测试并查看会发生什么。

有一种方法可以找到一个好的HELPER(实际上,它已经准备好成为您的y_轴)

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

例如:


如果(ax我所做的,前提是
X0
Y0

  • A=[-Y,X,0]
  • 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=0
    Y=0
    ,则
    A=[1,0,0]
    B=[0,1,0]
    ,对于好的辅助向量:找到绝对值最小的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);
    }
    
    absX=abs(X.X);absY=abs(X.y);absZ=abs(X.z);
    if(absXelse//absX我认为单位向量中所有元素的最小-最大磁度始终大于0.577,因此您可以忽略以下情况:

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


    谢谢你的回答。是的,HELPER远不能与X并行。我正在为android平台开发,我希望会有一些技巧来计算至少第一个并行向量,而且要便宜一些。我会给这个问题一些时间,如果没有更好的答案,我会接受这个答案。不,这不是唯一的问题这也不一定是最好的方法,这取决于HELPER的值。另外还引入了另一种数学上精确但数值上不稳定的计算。请解释“不稳定”。能否提供一个(非零)例如,它失败了吗?例如,如果X和Y的大小不同,则对它们进行平方运算将产生代数上正确但数值上不正确的结果。当Y与X相比足够大时,XX+YY将减小为Y*Y。输入向量根据OP进行归一化,因此最坏的情况是
    [1,ε,0]
    其中ε是机器精度。结果将是
    [-ε,1,0]
    [0,0,1]
    ,这仍然是零空间。我真的完全看不到你的观点(在本例中)。你可能会认为
    [ε,ε,1]
    case失败了,但在最后一步中对结果进行规范化后,结果就正确了。不要伪造现代计算机内部使用80位浮点进行计算,但最终只显示32或64位。有哪种算法符合您的需要吗?它们涉及以稳健高效的方式生成y_轴。这几乎是一个相同的问题stion as:[对于一个正交向量,只需交叉乘积即可生成第二个向量。
    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")
    }