四元数 - 如何限制轴?

5
有没有可能限制四元数只在x和y轴上移动(就像欧拉角-偏航和俯仰一样,而不是滚动)?是否有类似的方程或公式可以实现这一点?
一些示例:
运动应该像这样:http://360.art.pl/experimental/1/。但是当我使用四元数构建我的播放器时,它没有限制,我不知道如何解决http://360.art.pl/experimental/2/

我很乐意帮忙,但四元数让我感到困惑。你可能会在Gamedev.se上找到一些有用的关于这个问题的信息:http://gamedev.stackexchange.com/search?q=quaternion - glenatron
链接失效了,伙计。你能再发一个吗? - Parth
2个回答

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 是二次的。例如,对于 local_right=(1,0,0)up_vector=(0,0,1),它变成了 dot(q*(1i+0j+0k)*conj(q), 0i+0j+1k)=2*x*z-2*w*y=0,其中 q=w+xi+yi+zk

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

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

假设 [a, b] 是一个具有实部 a 和虚部 b 的四元数。可以通过计算 exp(ln(x)/2)(这些函数也在维基上)来计算 Sqrt(x)。您还可以尝试使用 exp(ln(x)/2*tick*realign_rate) 替换 sqrt,以实现上向量的平滑恢复 :)。或者反过来,简化公式:

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

另请参阅https://dev59.com/SnM_5IYBdhLWcg3w6HzT#1171995

编辑:校正向量,添加约束条件。


0

首先让我描述一下你所说的约束类型。给定一个world_up向量,您希望限制旋转,使其相对于相机垂直显示。如果相机视图坐标被标记为camera_upcamera_rightcamera_forward

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

这可以直接完成(例如,在类似于{{link1: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)

回答问题:我可能错了,但我认为在四元数方面实现这种约束并不直观。更容易的方法是像上面那样生成旋转矩阵,然后将其 转换为四元数
这确实引出了一个问题:你试图通过在这里使用四元数解决什么问题?
  • 如果您需要四元数与其他系统或库交互,那没问题。
  • 如果您试图修复错误行为,即场景在视点靠近天顶时快速旋转,请注意,这是您对约束的结果:无论如何实现它,它都会发生。
  • 如果您尝试使用四元数获得更自然的插值,请注意,您的约束使此无意义:自然的四元数插值将违反约束。鉴于约束条件,插值您的view_forward向量而不是四元数会更自然。

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