关于glm四元数旋转

5

我想使用四元数进行旋转。

glm库可以很好地实现这一点。

以下是我的代码:

vec3 v(0.0f, 0.0f, 1.0f);
float deg = 45.0f * 0.5f;
quat q(glm::cos(glm::radians(deg)), 0, glm::sin(glm::radians(deg)), 0);
vec3 newv = q*v;
printf("v %f %f %f \n", newv[0], newv[1], newv[2]);

我的问题是许多文章中的四元数旋转公式是什么

rotated_v = q*v*q_conj

这很奇怪。在glm中,向量“v”乘以四元数“q”就可以进行旋转。

这让我感到困惑。

2个回答

4

经过一些研究,我找到了glm四元数中操作“*”的定义以及其内部运作原理。

此实现基于以下网站:

Quaternion vector rotation optimisation

A faster quaternion-vector multiplication

这里有两个版本的四元数旋转。

//rotate vector 
vec3 qrot(vec4 q, vec3 v) 
{ 
    return v + 2.0*cross(q.xyz, cross(q.xyz,v) + q.w*v);
} 

//rotate vector (alternative) 
vec3 qrot_2(vec4 q, vec3 v)
{ 
    return v*(q.w*q.w - dot(q.xyz,q.xyz)) + 2.0*q.xyz*dot(q.xyz,v) +    
          2.0*q.w*cross(q.xyz,v);
} 

如果有人能证明这一点,我将不胜感激。


混淆源于 GLM 在四元数和 vec3 之间的乘法运算符。它不会执行四元数乘法,正如人们所认为的那样 - 它执行向量旋转操作,就像你上面描述的那样。因此,rotated_v = q*v*q_conj 将会给出错误的结果。请参见:链接 - omahena

1

当虚部与向量垂直时,四元数才能正常工作。

例如,当你的向量为vec3(0,sin(angle),0) 时,它与vec3(0,0,1)垂直;

当不正确时,你会发现需要乘以共轭。

其中q代表四元数,v代表向量。

通常情况下,当你执行q * v时,你会得到一个4D向量,即另一个四元数。我们只关心第一个分量,并假设其为0,即一个纯四元数。当你执行q * v * q'时,你可以确定得到一个纯四元数,从而转换为一个好的3D向量。

你可以测试非垂直的向量/四元数,你会发现你的旋转是不正确的。

https://www.3dgep.com/understanding-quaternions/


事实上,我曾尝试使用 q * v * q' 来获取旋转向量。但这是不正确的。 类似于以下代码: quat q(cos(radians(deg)), 0, sin(radians(deg)), 0); quat q_conj = conjugate(q); vec4 newv= vec4(0, v); newv = q*newv*q_conj; 然而,我得到的结果是 (0.000000, 0.000000, 0.000000,1.000000)。 - Junyu Ke
看起来好像什么都没做。 - Junyu Ke
我有一段工作正常的代码:quat tmp = mix(m_init,m_end,t); vec3 res= tmp * m_initTargetVector * conjugate(tmp)); 你不需要vec4“newv”。 - Paltoquet
好的,如果你看一下glm::rotate的定义,你会发现它只是做我所做的事情。return q * v;其中q是四元数,v是vec3。 - Junyu Ke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接