【问题标题】:Quaternions - how to limit axis?四元数 - 如何限制轴?
【发布时间】:2012-07-25 09:37:45
【问题描述】:

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

一些例子:

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

【问题讨论】:

标签: 3d quaternions


【解决方案1】:

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

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,虚部为bSqrt(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

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

【讨论】:

    【解决方案2】:

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

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

    这可以通过构造一组垂直坐标向量作为视图方向的函数来直接完成(例如,在LookAt()-like 函数中)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)
    

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

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

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

    【讨论】:

      猜你喜欢
      • 2015-05-27
      • 1970-01-01
      • 2012-03-14
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      • 2019-09-18
      • 1970-01-01
      • 2023-04-01
      相关资源
      最近更新 更多