3d 中的四元数旋转未按预期工作

问题描述 投票:0回答:0

我正在尝试了解四元数的工作原理以及在三维空间中实现任意旋转的正确方法是什么。

我使用 Vulkan 和 glm 进行渲染和 3D 数学计算。

我对三维旋转有一个基本的了解,也就是说,你需要一个旋转轴和一个角度,因此四元数很容易从 3d 向量和浮点数构造出来。我也明白四元数是一个四维数,也就是说,如果(x,y,z,w)是一个四元数,它并不像x,y,z是轴,w是角度那么简单。

最让我困惑的是我应该如何表达对象的旋转,最好是链接四元数,每次对象收到某种旋转命令时添加一个新的四元数,还是我应该一直只需要一个四元数。我问的原因是因为我希望对象在鼠标移动时绕 y 轴旋转,但我也希望它绕某个任意轴旋转,我们称之为 r,它垂直于 y 轴,但也当物体本身旋转时,它也绕 y 轴旋转。重点是,有两个主要旋转,y 和 r。

对象有多种操作,但设置旋转有

void rn_object_set_rotation(void* o, float x, float y, float z, float degrees) {

    Object object = (Object) o;

    versor q;

    glm_quat_identity(object->node->rotation);
    glm_quat(q, glm_rad(degrees), x, y, z);
    glm_quat_mul(object->node->rotation, q, object->node->rotation);

}

将旋转设置为任意轴和角度,并且

void rn_object_rotate(void* o, float x, float y, float z, float degrees) {

    Object object = (Object) o;

    versor q;

    glm_quat(q, glm_rad(degrees), x, y, z);
    glm_quat_mul(object->node->rotation, q, object->node->rotation);

}

“添加”旋转。

第一种方法可用于硬重置旋转,当您想要添加或更改旋转但以旧的作为参考(或起点)时,应使用第二种方法。

我不确定我的目标是否可以通过这种设置实现,我想象在对象中有两个四元数,一个用于 y 轴,一个用于 r 轴,然后在整个渲染循环中不断地将它们相乘,会起作用,但是那无法很好地扩展,而且看起来也不是很直观。

下图显示了我想要的绕 y 轴的旋转。

下一张图片显示了我想要的 r 轴(有点),如您所见,如果我绕 y 轴旋转它(我使用 [0.0, 1.0, 0.0] 作为轴调用旋转方法),物体实际上绕着倾斜的轴旋转,在最后的图像中,您可以看到物体如何指向上方,但我希望它像第一张(第四张)图像一样保持指向下方。我的猜测是旋转实际上发生在物体空间而不是世界空间?

最后,最后一张图片显示了关于 [1.0, 1.0, 0.0] (归一化)的旋转,角度为 0 度(使用 set_rotation),这让我很困惑,我猜角度为零,所以没有发生旋转,这是有道理的。

c rotation quaternions glm-math
© www.soinside.com 2019 - 2024. All rights reserved.