SoRoMan

人若无名,便可专心练剑.

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  12 随笔 :: 1 文章 :: 41 评论 :: 0 Trackbacks

3D空间中的旋转可用旋转矩阵、欧拉角或四元数等形式来表示,他们不过都是数学工具,其中在绕任意向量的旋转方面,旋转矩阵和四元数两种工具用的较多,欧拉角由于存在万向节死锁等问题,使用存在限制。

(本文假设坐标系为左手坐标系中,旋转方向为顺时针。)

所求问题:

给定任意单位轴q(向量),求向量p(x,y,z)(或点p)饶q旋转theta角度的变换后的新向量p'(或点p'):

1.用四元数工具:
-------------------------------------------------------------------------
结论:构造四元数变换p'= q*p*q-1,(p,q是由向量p,q扩展成的四元数)。那么,p'转换至对应的向量(或点)就是变换后的新向量p'(或点p')。

其中,p',q,p,q-1均为四元数。q由向量q扩展,为q=(cos(theta/2),sin(theta/2)*q),p由向量p扩展,为p=(0,x,y,z),q-1为q的逆,因为q为单位四元数,所以q-1=q*=(cos(theta/2),-sin(theta/2)*q)。
-------------------------------------------------------------------------

(这个结论的证明过程可以在网上找到。这里略去。)
下面看其时间复杂度:

首先有个三角函数的计算时间,这个可以预先计算好,花费时间不计。考虑n个四元数相乘需进行4*4*(n-1)=16*(n-1)次乘法,15*(n-1)次加法,因为加法化费时间较少,这里仅考虑乘法。这里涉及到三个四元数的乘法,设一次乘法的时间为T,故花费16*2=32T

2.旋转矩阵工具:
-------------------------------------------------------------------------
结论:构造旋转矩阵变换Trot,则变换后的新向量p'(或点p')为p'= p*Trot

其中,p'(x',y',z',1),p(x,y,z,1)为向量p',p的4D齐次坐标表示,Trot =

|t*x*x + c,       t*x*y + s*z,      t*x*z - s*y,     0|
|t*x*y - s*z,    t*y*y + c,          t*y*z + s*x,    0|
|t*x*z + s*y,   t*y*z - s*x,       t*z*z + c,        0|
|0,                    0,                       0,                    1|   

c=cos(theta), s=sin(theta),t=1-c.
-------------------------------------------------------------------------
(这个结论的证明过程可以在网上找到。这里略去。)

下面看其时间复杂度:

三角函数的计算时间不计。矩阵本身的元素乘法主要是计算t*x和s*x之类,需进行12+3=15次乘法。两个矩阵相乘的需进行n*n*n次乘法,这里n=4,所以花费4*4*4=64次乘法时间,但这里有个注意的地方就是旋转矩阵的第4维无须考虑,即可简化为3X3的矩阵。故花费3*3*3=27次乘法时间,总共的时间为15+27=42次乘法时间。cost=42T.

比较来看,还是使用四元数的效率要高出一些,这在要变换的点的数目越大时,体现的越明显。实际上,有很多3D引擎为了利用四元数运算的高效率性,一般先将矩阵转换成四元数后进行运算再转回为矩阵后,再传给DirectX或OpenGL库函数。

关于四元数和矩阵在向量(方向)之间的进行插值的效率比较,见下篇:
探讨:物体绕任意向量的旋转-四元数法VS.旋转矩阵法的性能比较

posted on 2006-09-19 17:11 SoRoMan 阅读(22000) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理