我有一个沿速度矢量移动的射弹物体。我需要确保物体始终面向速度矢量的方向。此外,我使用四元数而不是矩阵表示对象旋转。

我知道第一步是找到正交基础:

forward = direction of velocity vector
up = vector.new(0, 1, 0)
right = cross(up, forward) 
up = cross(forward, right)

如何将基础转换为旋转四元数?

<强>解决方案

请注意,我想赞扬Noel Hughes提供的答案,但我想用自己的经验来澄清。伪代码如下:

   vec3 vel = direction of velocity vector
   vec3 forward = (1, 0, 0)  // Depends on direction your model faces. See below.
   vec3 axis = cross(forward, vel)
   if (axis == 0) then quit // Already facing the right direction!
   axis = normalize(axis)
   float theta = acos(vel.x/sqrt(vel.x^2, vel.y^2, vel.z^2))
   quat result = (0, axis.y * sin(theta/2), axis.z * sin(theta/2), cos(theta/2)

四元数的最后一个元素是标量部分,前三个元素是虚部。此外,上述伪代码假定您的对象位于“模型空间”中。指向正x轴。在我的例子中,对象实际上指向正y轴,在这种情况下我做了以下更改:

   vec3 vel = direction of velocity vector
   vec3 forward = (0, 1, 0)  // Note that y-component is now 1
   vec3 axis = cross(forward, vel)
   if (axis == 0) then quit 
   axis = normalize(axis)
   float theta = acos(vel.x/sqrt(vel.x^2, vel.y^2, vel.z^2))
   quat result = (axis.x * sin(theta/2), 0, axis.z * sin(theta/2), cos(theta/2)
   // Note that SECOND component above is now 0
有帮助吗?

解决方案

我假设您不关心射弹的方向,除了使纵轴与速度矢量对齐,并且纵轴是(1,0,0)的x轴。

你走在正确的轨道上。将速度矢量(vx,vy,vz)/ sqrt(vx ^ 2 + vy ^ 2 + vz ^ 2)与x轴交叉归一化,并对结果进行归一化 - (0,yn,zn) - 这就是旋转四元数的轴。旋转角度简单地是t = vx / sqrt的反余弦值(vx ^ 2 + vy ^ 2 + vz ^ 2)。然后产生四元数

(0,yn,zn)sn(theta / 2)cos(theta / 2)

如果您有任何问题,请与我们联系。

诺埃尔休斯 nhughes1ster@gmail.com

其他提示

我看看 vecmath库(Java)。它已经存在了很长时间,我们在社区中使用它。它基于4元组,如果没有直接的转换方法,我会很失望。

我还会为预期结果编写单元测试。混淆正面和负面,左手和右手以及movinig /参考框架非常容易。从简单的(例如xyz)开始,以确保您有正确的答案。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top