5

是否有可能限制四元数仅在 x 和 y 轴上移动(如欧拉 - 偏航和俯仰,不滚动)?我有什么方程式或类似的东西可以做到这一点吗?

一些例子:

运动应该像这样:http: //360.art.pl/experimental/1/
但是当我在四元数上构建我的播放器时,它没有限制,我不知道如何修复它http://360.art。 pl/实验性/2/

4

2 回答 2

0

让我首先描述一下您正在谈论的那种约束。给定一个world_up向量,您希望限制旋转,使其相对于相机看起来是垂直的。如果相机视图坐标标记为camera_upcamera_rightcamera_forward

constrain rotation matrix R such that:  dot(R*world_up, camera_right) == 0

这可以LookAt()通过构造一组垂直坐标向量作为视图方向的函数来直接完成(例如,类似函数)view_forward

given vectors:  view_forward, world_up

Rot_forward = normalize(view_forward)
Rot_right = normalize( cross(view_forward, world_up) )
Rot_up = cross(Rot_right, Rot_forward)

回答这个问题:我可能是错的,但我认为这种约束在四元数方面并不容易实现。如上所述生成旋转矩阵并将其转换为 quaternion会更容易。

这确实提出了一个问题:你想通过在这里使用四元数来解决什么问题?

  • 如果您需要四元数与其他系统或库交互,那很好。
  • 如果您正在尝试修复不良行为,即当您的视点接近天顶时场景会快速旋转,请注意这是您的约束的结果:无论您如何实现它,它都会发生。
  • 如果您尝试使用四元数来获得更自然的插值,请注意您的约束会导致此问题:自然四元数插值将违反约束。view_forward鉴于约束,插入向量而不是四元数会更自然。
于 2012-07-25T19:16:33.513 回答
0

您可以尝试直接从偏航/俯仰构造四元数:

q = quat_from_axis_angle(up_vector, yaw) * quat_from_axis_angle(local_right, pitch)

(您可能必须以相反的顺序将它们相乘,具体取决于您将它们转换为旋转矩阵的方式),或者每次更改它们时重新对齐它们:

rotated_right = apply_rotation(q, local_right);
projected_right = rotated_right - dot(rotated_right, up_vector) * up_vector;
realign = quat_align_vector(rotated_right, normalized(projected_right));
q = realign * q

projected_right这是rotated_right在水平面上的投影。如果不滚动,这两个向量必须相同,这意味着dot(rotated_right, up_vector) = 0。最后一个等式是必须满足的实际约束。它是 中的二次方q。例如 for local_right=(1,0,0), and up_vector=(0,0,1), 它变成dot(q*(1i+0j+0k)*conj(q), 0i+0j+1k)=2*x*z-2*w*y=0, with q=w+xi+yi+zk

您可以在http://en.wikipedia.org/wiki/Quaternionhttp://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation找到quat_from_axis_angle和的公式。至于,一种方法是apply_rotationquat_align_vector

quat_align_vector(src, dst) = sqrt([dot(src, dst), cross(src, dst)])

with [a, b]beign 一个 实 部a和 虚部的 四元数b. Sqrt(x)可以计算为exp(ln(x)/2)(这些函数也在 wiki 上)。您也可以尝试将 sqrt 替换exp(ln(x)/2*tick*realign_rate)为平滑恢复向上向量 :) 。或者反过来,稍微简化一下公式:

quat_align_vector(src, dst) = [dot(halfway, dst), cross(halfway, dst)],
halfway = normalized(normalized(src) + normalized(dst))

另请参阅https://stackoverflow.com/a/1171995

编辑:更正向量,添加约束。

于 2012-07-30T15:46:27.610 回答