Math 从两个3D矢量定义的旋转计算3x3旋转矩阵的有效方法

Math 从两个3D矢量定义的旋转计算3x3旋转矩阵的有效方法,math,matrix,Math,Matrix,虽然我已经找到了两种解决方案,但我很好奇是否有众所周知的方法来执行此操作,因为这似乎是一项相当常见的任务 下面是psudo代码的两个明显的方法 轴角 这是非常合乎逻辑的,但是调用两次sin,调用一次cos(在角度计算和轴角度到矩阵转换中) Matrix3x3在向量到矩阵之间的旋转(常数向量v1,常数向量v2) { 角度=v1.角度(v2); 轴=v1.交叉(v2); /*这方面的数学是众所周知的*/ 矩阵x3x3矩阵=轴角度到矩阵(轴,角度); 收益矩阵; } 编辑:最简单的功能是速度非常慢,

虽然我已经找到了两种解决方案,但我很好奇是否有众所周知的方法来执行此操作,因为这似乎是一项相当常见的任务

下面是psudo代码的两个明显的方法

轴角 这是非常合乎逻辑的,但是调用两次
sin
,调用一次
cos
(在角度计算和轴角度到矩阵转换中)

Matrix3x3在向量到矩阵之间的旋转(常数向量v1,常数向量v2)
{
角度=v1.角度(v2);
轴=v1.交叉(v2);
/*这方面的数学是众所周知的*/
矩阵x3x3矩阵=轴角度到矩阵(轴,角度);
收益矩阵;
}
编辑:最简单的功能是速度非常慢,但是正如在这里的回复中所指出的:通过分别从轴长度和
v1、v2
点积获得
angle\u sin
angle\u cos
,可以避免计算角度

两个矩阵之间的差异 这里是我发现的另一种方法,它从向量构造两个3x3矩阵并返回差分

但是,这比可以优化的轴/角度计算慢(如上所述)

注意。这假设两个向量都是标准化的,矩阵是主列(OpenGL)

Matrix3x3在向量到矩阵之间的旋转(常数向量v1,常数向量v2)
{
矩阵x3x3m1,m2;
轴=v1.交叉(v2);
axis.normalize();
/*构造2个矩阵*/
m1[0]=v1;
m2[0]=v2;
m1[1]=轴;
m2[1]=轴;
m1[2]=m1[1]。交叉(m1[0]);
m2[2]=m2[1]。交叉(m2[0]);
/*计算m1和m2之间的差值*/
m1.转置();
矩阵x3x3矩阵=m2*m1;
收益矩阵;
}
是否有更好的方法执行此计算

编辑:此问题的目的不是对每种方法进行微观优化和基准测试。取而代之的是,我很好奇是否有一些我不知道的完全不同和优越的方法



注意:我特意省略了共线向量退化情况的检查(其中轴长度为零),以保持示例的简单性。

您发布的两种方法都可以优化

方法1 与其使用
acos
查找两个向量之间的角度,更好的做法是避免查找角度。怎么用?罗德里格斯提出的方法只需要
sinθ
cosθ
1-cosθ
,因此找到实际角度是多余的

我们知道
v1
v2
是单位向量
v1·v2=|v1 | v2 | cosθ
由于
v1 |=| v2 |=1
v1·v2
直接给出了
cosθ
,找到
1-cosθ
并不昂贵
v1×v2=|v1 | v2 | sinθn=sinθn
,其中
n
是垂直于
v1
v2
的单位向量,发现
v1×v2
叉积的大小将直接给出
sinθ

现在我们已经有了sinθ和cosθ,我们可以通过使用Rodrigues forumla直接形成旋转矩阵;(尽管佩奇声称使用四元数数学,但这是轴角度到矩阵的转换公式)

方法2 将两个正交帧构造为矩阵后,可以避免进行第二次转置。这是证据

假设
A
B
是两个矩阵,因为您想从
A
旋转到
B
我们需要一些矩阵
X
,当与
A
相乘时,将得到
B

XA=B

X=BA⁻⑨

这就是你所需要的;当您将
X
预乘到
A
时,您将得到
B
。但是,您发现的是
Y

Y=AB⁻⑨

YB=A

然后将
Y
转置为
Y⁻CharStyle

Y⁻⑩YB=Y⁻ñA

B=Y⁻ñA

不用做两个倒换(这里是转置),你只需要做上面的方法,它只涉及一个转置


我仍然认为,如果不以优化的形式对方法进行基准测试,我们就不能说方法2比方法1快。因此,我强烈建议您在这两种方法之间进行基准测试(使用一些非平凡的负载),然后得出结论。

轴角方法是最快的方法,下面是我提出的用于高效轴/角度到3x3矩阵转换的C代码

这也检查了共线情况

注意:如果您有自己的数学库,您可能可以在不包含任何相关函数的情况下在_vecs_到_mat3之间进行旋转

#包括
#包括
/* -------------------------------------------------------------------- */
/*数学库声明*/
静态孔隙单位_m3(浮动m[3][3]);
静态浮点点_v3v3(常数浮点a[3],常数浮点b[3]);
静态浮点归一化_v3(浮点n[3]);
静态空隙交叉(浮点数r[3],常数浮点数a[3],常数浮点数b[3]);
静态空区mul_v3_v3fl(浮点数r[3],常数浮点数a[3],浮点数f);
静态空洞正交(float p[3],常数float v[3]);
静态空隙轴\u角度\u标准化\u至\u mat3\u ex(
浮动垫[3][3],常数浮动轴[3],
恒浮角(sin,恒浮角(cos));
/* -------------------------------------------------------------------- */
/*主要功能*/
在向量u到mat3之间的无效旋转(浮点m[3][3],常量浮点v1[3],常量浮点v2[3]);
/**
*从2个标准化向量计算旋转矩阵。
*
*v1和v2必须是单位长度。
*/
无效旋转\u在\u向量\u到\u mat3之间(浮点m[3][3],常量浮点v1[3],常量浮点v2[3])
{
浮动轴[3];
/*避免计算角度*/
浮子角;
浮动角;
十字轴v3十字轴v3v3(轴,v1,v2);
角度_sin=标准化_v3(轴);
角度cos=点