0

我正在寻找一种方法来确定相机 ( a) 是否与特定对象 ( b) 看向相同的方向。

我只处理旋转,因为在这里我们不关心位置(所以我们可以认为两者都位于原点)。

我正在使用 gl-matrix 处理四元数。

经过多次搜索和测试,我了解到我可以使用点积确定两个四元数之间的“距离”(大小?)。

var a = quat.create();
quat.rotateY(a, a, Math.PI);

var b = quat.create();
quat.rotateY(b, b, Math.PI);

quat.dot(a, b)

这在许多情况下都很好用(它返回范围 [0..1] 内的数字:从1如果两者都完全看同一个方向到0如果两者完全相反)。

但是,就我而言,我不想关心对象之间的“滚动”。我的意思是相机 ( a) 可以倒置,相对于 ( b),但仍然看着同一点。

例如,如果我b绕 Z 转 180 度,我得到一个在 周围的点积0,而它仍然看向同一个方向。

var a = quat.create();
quat.rotateY(a, a, Math.PI);

var b = quat.create();
quat.rotateY(b, b, Math.PI);
quat.rotateZ(b, b, Math.PI);

quat.dot(a, b);

我尝试了很多事情,例如将ab, or的倒数相乘[s]lerp,但我仍然无法得到任何符合我要求的东西。

当然,我不能简单地分离和使用绝对 Z 轴,因为这里的一切都是相对的,所以滚动可以围绕任何轴。

我怎样才能得到那个结果?

编辑:感谢 LutzL 的回答,这是我实施解决方案的方式:

var r = quat.create();
quat.invert(r, a);
quat.multiply(r, r, b);

var distance = r[3]*r[3] - r[0]*r[0] - r[1]*r[1] + r[2]*r[2];
4

2 回答 2

1

我将它解释为 Z 轴的单位矢量(在局部坐标中)是您的前向矢量吗?

四元数 a 描述了局部坐标系到全局坐标系的转换。因此,局部坐标中的向量 v 在全局坐标系中具有方向 a*v*a'(a'=a=a=inverse for unit quaternion)的共轭。Z轴的方向因此根据ka=a*k*a'而改变。

因此,第二个对象的 Z 方向为 kb=b*k*b'。它们之间夹角的余弦是 ka 和 kb 的标量积,也是 ka'*kb=a*k'*a'*b*k*b' 的实部。任何四元数 v 的实部在 a'*v*a 中保持不变,所以

scal(ka,kb) = 实数(ka * kb')

= -real( k * a' * b * k * b' * a ) = -real( k * (a' * b) * k * (a'* b)' )

我不知道 GL 实现的细节,但操作是计算乘积 p1=a'*b,将 p1 绕 Z 轴旋转 180 度到 p2,实际上只是翻转 i 的符号和 j 系数,并形成 p1 和 p2 的标量积。简短的版本是

scal(ka,kb) = p1.w*p1.w - p1.x*p1.x - p1.y*p1.y + p1.z*p1.z

于 2014-04-25T16:21:36.967 回答
0
  1. 找到 2 个向量 dirA 和 dirB ,即相机和物体的方向。您可以通过相应的四元数简单地变换向量 Z(0,0,1)。

  2. 找到向量 dirA dirB 之间的角度

    角度= atan2(交叉(dirA,dirB).len(),点(dirS,dirB))

于 2014-04-26T06:29:29.553 回答