Math 计算与3D中第三个向量垂直的两个向量
计算两个垂直于第三个向量(X)且彼此垂直的向量的最佳(最快)方法是什么 这就是我现在计算向量的方法: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); 我知道有无限多的解决方案,我不在乎哪一个是我的解决方案 这个问题的背后是什么:我需要构造变换矩
// 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(absX else//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")
}