本文源自:http://ogldev.atspace.co.uk/www/tutorial07/tutorial07.html
[tor]
Rotation Transformation
Background
我们要讲的下一个变换是旋转变换,给定一个角度和点,随后使点绕着其中一个轴进行旋转。我们经常改变X、Y和Z红的其中两个,另外一个则保持不变。这样一来,点走过的路径会在三个主要的平面上:XY(绕着Z轴旋转的时候),YZ(绕着X轴旋转的时候)和XZ(绕着Y轴旋转的时候)。当然还有更复杂的旋转变换,你可以绕任意一个向量进行旋转,当然我们现在不需要了解这个。
然我们根据概述来定义问题。思考一下下面的图表:
把(x1,y1)点绕着圆圈旋转到(x2,y2)点。换句话说我们想对(x1,y1)旋转alpha2。我们先假定圆圈的半径为1。那么会有以下等式:
x 1 =cos(α 1 )y 1 =sin(α 1 )x 2 =cos(α 1 +α 2 )x 2 =sin(α 1 +α 2 )
我们用下面的三角函数来展开x2,y2
cos(α+β)=cos(α)⋅cos(β)−sin(α)⋅sin(β)sin(α+β)=sin(α)⋅cos(β)+sin(α)⋅cos(β)
通过上面的三角函数可以写出:
x 1 =cos(a 1 +a 2 )=cos(a 1 )⋅cos(a 2 )−sin(a 1 )⋅sin(a 2 )=x 1 ⋅cos(a 2 )−y 1 ⋅sin(a 2 )y 2 =sin(a 1 +a 2 )=sin(a 1 )⋅cos(a 2 )+cos(a 1 )⋅sin(a 2 )=y 1 ⋅cos(a 2 )+x 1 ⋅sin(a 2 )
在上面的图表中,我们看向XY平面而Z轴直接指向着页面。如果X或者Y是四维向量的一部分,所以上面的的等式可以写成矩阵的形式(矩阵不影响Z或W)
⎡ ⎣ ⎢ ⎢ ⎢ ⎢ cosαsinα00 −sinαcosα00 0010 0001 ⎤ ⎦ ⎥ ⎥ ⎥ ⎥ ⋅⎡ ⎣ ⎢ ⎢ ⎢ ⎢ xyzw ⎤ ⎦ ⎥ ⎥ ⎥ ⎥ =⎡ ⎣ ⎢ ⎢ ⎢ ⎢ x⋅cosα−y⋅sinαx⋅sinα+y⋅cosαz1 ⎤ ⎦ ⎥ ⎥ ⎥ ⎥
如果你想绕着Y和Z轴旋转,那么等式也是极其类似了但是矩阵会有轻微的变化。下面就是绕着Y轴旋转的矩阵。
⎡ ⎣ ⎢ ⎢ ⎢ ⎢ cosα0sinα0 0000 −sinα1cosα0 0001 ⎤ ⎦ ⎥ ⎥ ⎥ ⎥ ⋅⎡ ⎣ ⎢ ⎢ ⎢ ⎢ xyzw ⎤ ⎦ ⎥ ⎥ ⎥ ⎥ =⎡ ⎣ ⎢ ⎢ ⎢ ⎢ x⋅cosα−z⋅sinαyx⋅sinα+z⋅cosα1 ⎤ ⎦ ⎥ ⎥ ⎥ ⎥
绕着X轴旋转的等式:
⎡ ⎣ ⎢ ⎢ ⎢ ⎢ 1000 0cosαsinα0 0−sinαcosα0 0001 ⎤ ⎦ ⎥ ⎥ ⎥ ⎥ ⋅⎡ ⎣ ⎢ ⎢ ⎢ ⎢ xyzw ⎤ ⎦ ⎥ ⎥ ⎥ ⎥ =⎡ ⎣ ⎢ ⎢ ⎢ ⎢ xy⋅cosα−z⋅sinαy⋅sinα+z⋅cosα1 ⎤ ⎦ ⎥ ⎥ ⎥ ⎥
Source walkthru
这个教程中的代码变化及其简短。我们只改变代码中一个变换矩阵。
World.m[0][0]=cosf(Scale); World.m[0][1]=-sinf(Scale); World.m[0][2]=0.0f; World.m[0][3]=0.0f;
World.m[1][0]=sinf(Scale); World.m[1][1]=cosf(Scale); World.m[1][2]=0.0f; World.m[1][3]=0.0f;
World.m[2][0]=0.0f; World.m[2][1]=0.0f; World.m[2][2]=1.0f; World.m[2][3]=0.0f;
World.m[3][0]=0.0f; World.m[3][1]=0.0f; World.m[3][2]=0.0f; World.m[3][3]=1.0f;
当绕着Z轴旋转的时候,你也可以尝试其他的旋转,但是我认为没有经过从3D到2D的投影处理,旋转看起来会很无趣。我们会在后面的几个教程里面完成所有管线的变换。