关于如何建立绕任意轴旋转的旋转矩阵的编程与实践
作者:akinggw
前言
最近在看一本3D理论方面的书,叫《3D游戏:…》跟FLY3D有关。虽然看的不是太懂,但还是有那么一点点感觉。关于如何建立绕任意轴旋转的旋转矩阵,这个问题,书上也讲过,然后在网上也看了几篇这样的文章。我觉得这两篇不错,可以看一下。
向量几何在游戏编程中的使用
http://www.86vr.com/scripts/print.asp?did=5771&page=2
3D演讲稿
它们讲的都是些理论的东西,没有实际代码。我在这里就根据这些理论然后来阐述FLY3D相关的代码,很容易懂的。
任意轴旋转
为什么这里要强调任意轴旋转呢?因为基本的旋转包括对X,Y,Z三个轴的旋转。而任意轴旋转就是在任意一个角度,任意一个方向都可以旋转。
对于单一轴的旋转,我在这里就不多说,是地球人都知道了,下面我就说说关于任意轴的旋转。首先,我们阐述一下任意轴旋转的基本理论,很多文章都是用书面的语言阐述的,但《3D演讲稿》中的图形更能说明问题。我们下面看一下:
![]() |
图注1 |
上面这张图显示了实现任意轴旋转的组成结构和过程。我想这里不应该我来说了吧,如果不明白,去找一篇理论方面的文章看一下,然后再看看图,就什么都明白了
![]() |
图注2 |
这张图显示了如何构造第一张图中提到的三个矢量。如果看不懂也没关系,最主要的是记住后面的那个公式。
![]() |
图注3 |
这张图数学地说明了我们的任意轴旋转的实现过程。
![]() |
图注4 |
任意轴旋转的公式在这里,我们只要用程序实现上面这个公式就可以了。
下面,我们来看一下FLY3D中是如何实现的:
void flyMatrix::set_rotation( float ang, const flyVector& dir2 )
{
flyVector dir(dir2);
dir.normalize();
ang*=-FLY_PIOVER180;
float fCos=cosf( ang );
float fSin=sinf( ang );
m[0][0] = ( dir.x * dir.x ) * ( 1.0f - fCos ) + fCos;
m[0][1] = ( dir.x * dir.y ) * ( 1.0f - fCos ) - (dir.z * fSin);
m[0][2] = ( dir.x * dir.z ) * ( 1.0f - fCos ) + (dir.y * fSin);
m[1][0] = ( dir.y * dir.x ) * ( 1.0f - fCos ) + (dir.z * fSin);
m[1][1] = ( dir.y * dir.y ) * ( 1.0f - fCos ) + fCos ;
m[1][2] = ( dir.y * dir.z ) * ( 1.0f - fCos ) - (dir.x * fSin);
m[2][0] = ( dir.z * dir.x ) * ( 1.0f - fCos ) - (dir.y * fSin);
m[2][1] = ( dir.z * dir.y ) * ( 1.0f - fCos ) + (dir.x * fSin);
m[2][2] = ( dir.z * dir.z ) * ( 1.0f - fCos ) + fCos;
m[0][3] = m[1][3] = m[2][3] = 0;
m[3][0] = m[3][1] = m[3][2] = 0;
m[3][3] = 1;
}
这个函数的作用就是计算任意轴旋转的矩阵,只要这个矩阵计算出来,就可以实现物体的任意轴旋转。
OK ,就到这里了吧。