四元数 - 旋转 [英] Quaternion - Rotate To

查看:101
本文介绍了四元数 - 旋转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在世界空间有一些对象,让我们说(0,0,0),并把它旋转到面(10,10,10)。



解决方案

这个问题没有意义。你说你想要一个对象面对一个特定的点,但是没有给出足够的信息。



首先,面对方向是什么意思?在OpenGL中,这意味着本地参考系中的 -z 轴与某些外部参考系中的指定方向对齐。为了使这种对准发生,我们需要知道对象的相关轴当前面向的方向。



但是,仍然没有定义唯一的转换。即使你知道用什么方向制作 -z 轴点,对象仍然可以自由旋转 该轴。这就是为什么函数 gluLookAt()要求你提供一个'at'方向向上的方向。



接下来我们需要知道的是什么格式的最终​​结果需要在?对象的方向通常以四元数格式存储。但是,如果您想以图形方式旋转对象,那么您可能需要一个旋转矩阵。



因此,让我们做一些假设。我假设你的对象居中在世界的点 c ,并且具有默认对齐方式。也就是说,对象的 x y z 轴与世界的 x z 轴。这意味着对象相对于世界的方向可以表示为单位矩阵或者标识四元数: [1 0 0 0] (使用四元数



如果希望最短的旋转将对齐对象的 -z 轴与点 p := [px py pz],那么您将围绕轴 a 旋转φ。现在我们将找到这些值。首先,我们通过对向量 pc 进行归一化,然后使用单位长度 -z 向量取交叉乘积,然后再次进行归一化,从而找到 a < :



a =正规化(crossProduct( -z ,规范化));



这两个单位向量之间的最短角度通过取其点乘的反余弦得到:



φ= acos(dotProduct( -z ,normalize( pc )));



这是由两个向量形成的角度的绝对值的度量。我们需要确定在 a 周围旋转时是正还是负。必须有一个更优雅的方式,但是第一种方式是找到一个第三轴,垂直于 a -z ,然后从其与我们的目标轴的点积。 Vis:



b = crossProduct( a -z ); p>

if(dotProduct( b ,normalize( pc ))< 0)φ=-φ;



一旦我们拥有了我们的轴和角度,就将它变成四元数是很容易的:



q = [cos(φ/ 2)sin(φ/ 2) a ];



这个新的四元数表示对象的新方向。它可以转换为矩阵用于渲染目的,或者您可以使用它直接旋转对象的顶点,如果需要,使用四元数乘法的规则。


I have some object in world space, let's say at (0,0,0) and want to rotate it to face (10,10,10).

How do i do this using quaternions?

解决方案

This question doesn't quite make sense. You said that you want an object to "face" a specific point, but that doesn't give enough information.

First, what does it mean to face that direction? In OpenGL, it means that the -z axis in the local reference frame is aligned with the specified direction in some external reference frame. In order to make this alignment happen, we need to know what direction the relevant axis of the object is currently "facing".

However, that still doesn't define a unique transformation. Even if you know what direction to make the -z axis point, the object is still free to spin around that axis. This is why the function gluLookAt() requires that you provide an 'at' direction and an 'up' direction.

The next thing that we need to know is what format does the end-result need to be in? The orientation of an object is often stored in quaternion format. However, if you want to graphically rotate the object, then you might need a rotation matrix.

So let's make a few assumptions. I'll assume that your object is centered at the world's point c and has the default alignment. I.e., the object's x, y, and z axes are aligned with the world's x, y, and z axes. This means that the orientation of the object, relative to the world, can be represented as the identity matrix, or the identity quaternion: [1 0 0 0] (using the quaternion convention where w comes first).

If you want the shortest rotation that will align the object's -z axis with point p:=[p.x p.y p.z], then you will rotate by φ around axis a. Now we'll find those values. First we find axis a by normalizing the vector p-c and then taking the cross-product with the unit-length -z vector and then normalizing again:

a = normalize( crossProduct(-z, normalize(p-c) ) );

The shortest angle between those two unit vectors found by taking the inverse cosine of their dot-product:

φ = acos( dotProduct(-z, normalize(p-c) ));

Unfortunately, this is a measure of the absolute value of the angle formed by the two vectors. We need to figure out if it's positive or negative when rotating around a. There must be a more elegant way, but the first way that comes to mind is to find a third axis, perpendicular to both a and -z and then take the sign from its dot-product with our target axis. Vis:

b = crossProduct(a, -z );

if ( dotProduct(b, normalize(p-c) )<0 ) φ = -φ;

Once we have our axis and angle, turning it into a quaternion is easy:

q = [cos(φ/2) sin(φ/2)a];

This new quaternion represents the new orientation of the object. It can be converted into a matrix for rendering purposes, or you can use it to directly rotate the object's vertices, if desired, using the rules of quaternion multiplication.

这篇关于四元数 - 旋转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆