如何使用四元数描述大于360度的旋转角度?

5

我正在尝试使用四元数进行旋转动画。 我的算法创建四元数,并在每一帧进行球面线性插值(slerp)。 以下是我用轴和旋转角度构建四元数的代码。

template <typename U>
Quaternion(Vector3<U> vec, const float& angle)
{
    vec.normalize();
    float cosa = cos(angle/2);
    float sina = sin(angle/2);
    w = cosa;
    x = sina * vec.x;
    y = sina * vec.y;
    z = sina * vec.z;
}

后来我发现当我尝试旋转4π弧度时,动画无法正常工作,因为我创建的四元数相当于0度。 我想知道四元数是否可以表示超过360度的旋转?或者我的动画算法需要改进吗?


1
"我试图旋转4π度",你是指4π弧度吗?sincos使用弧度而非角度。 - Blaze
是的,我指的是弧度。抱歉我的英语不好。 - M.Zhao
顺便说一句,你正在尝试做一件不寻常的事情。假设你有两个旋转(A、B),它们都围绕某个轴进行了大量旋转(>360)。如果不是平凡的方法(忽略“多余”的旋转,并将旋转视为“模360”,即仅使用旋转的末位姿态),你期望如何在它们之间进行插值? - geza
3个回答

5

我想知道四元数能否表示超过360度的旋转?

不行。

在范围[360;720]之间的四元数将被视为另一方向上的旋转:[-360;0]。

而在范围[720*k; 720*(k+1)]之间的四元数将被视为[0;720]范围内的旋转。

如果您使用slerp进行此类动画,四元数并不适合。

四元数只能在小于360度的角度之间进行slerp。

如果您仍想这样做,请使用其他表示方法,例如轴角。


另一种可能性是将旋转分成圆扇形,所有圆扇形的角度都低于最高角度。 - Arne Vogel
谢谢你的帮助。我会尝试使用轴角来进行动画制作。 - M.Zhao

1

将物体旋转360度等同于将其旋转0度。如果要旋转大于360度的角度alpha,只需旋转alpha-360或更一般地旋转alpha % 360

(这里的360是2pi的同义词,当然你需要注意角度与弧度之间的转换。不确定是否打错了,但360度应该是2pi而不是4pi)

附注:实际上,我认为你的代码没有问题,也许你不需要做任何改变。只是你的期望有误:通过旋转4pi得到的结果应该与旋转0度得到的结果相同。


但是对于动画来说就不同了。当我使用欧拉角时会很好用。 - M.Zhao
@M.Zhao 其实缺少的是一种它无法正常运作的情况。你在问题中所描述的并不真的是个问题,而你所得到的结果也是预期的。 - 463035818_is_not_a_number

1
将四元数视为即时旋转 - 瞬间旋转4π弧度与什么都不做相同。
当您动画旋转4π弧度超过20秒时,这不是您想要的。 您可以通过创建欧拉向量(一个三维向量,其方向表示旋转轴,与四元数相同,而其长度表示旋转的速度/角度)来解决此问题,请参见https://en.wikipedia.org/wiki/Axis%E2%80%93angle_representation。稍后,将其乘以经过的时间并根据图形需要将其转换为四元数或3D矩阵。

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