这里主要在前些章节基础上增加了对

 
1.
InBlock.gif public void Rotate( float angle, float x, float y, float z)
InBlock.gif        SharpGL.OpenGL 的成员
InBlock.gif
2.
InBlock.gif public void Rotate( float anglex, float angley, float anglez)
InBlock.gif        SharpGL.OpenGL 的成员
InBlock.gif
InBlock.gif public void Rotate( double angle, double x, double y, double z)
InBlock.gif        SharpGL.OpenGL 的成员
InBlock.gif
这两个重载函数的应用,我这里主要使用了
InBlock.gif public void Rotate( float angle, float x, float y, float z)
这个以类似四元数为参数的方法。
 

叙述一下这两个重载方法的区别:

我的专业是导航制导与控制,所以对这方面比较了解,在空间矢量的旋转以及坐标系转换等方面,四元数法有着比欧拉角法更加突出的优点,主要表现在捷联解算(陀螺,加速度计惯性系统)时的计算量小和没有奇点。而第二种方法实际上是以欧拉角为参数的旋转方法,他有个先天的缺点就是三角函数计算时的非线性和在东北天坐标系(任何右手坐标系)的俯仰角为90度的情况下存在奇点,此时无法进行解算,必须特殊处理(我所知道的有双欧法)。这些是题外话,如果你能够看懂更好,看不懂的话不影响以后的学习。

在上一节的基础上增加了几行代码后OpenGLDraw函数响应代码如下:

InBlock.gif float rtri = 0;
InBlock.gif float rquad = 0;
InBlock.gif
InBlock.gif private void openGLControl1_OpenGLDraw( object sender, PaintEventArgs e)
InBlock.gif{
InBlock.gif
InBlock.gif                         // Get the OpenGL object, just to clean up the code.
InBlock.gif                        SharpGL.OpenGL gl = this.openGLControl1.OpenGL;
InBlock.gif
InBlock.gif                        gl.Clear(OpenGL.COLOR_BUFFER_BIT | OpenGL.DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
InBlock.gif                        gl.LoadIdentity();             // Reset The View
InBlock.gif                        gl.Translate(-1.5f, 0.0f, -6.0f);         // Move Left And Into The Screen
InBlock.gif                        
InBlock.gif                        gl.Rotate(rtri,0.0f,1.0f,0.0f); //表示其绕y轴旋转,旋转角度为rtri中所代表的角度
InBlock.gif                        gl.Begin(OpenGL.TRIANGLES);             // Start Drawing The Pyramid
InBlock.gif                        gl.Color(1.0f, 0.0f, 0.0f);         // Red
InBlock.gif                        gl.Vertex(0.0f, 1.0f, 0.0f);         // Top Of Triangle (Front)
InBlock.gif                        gl.Color(0.0f, 1.0f, 0.0f);         // Green
InBlock.gif                        gl.Vertex(-1.0f, -1.0f, 0.0f);         // Left Of Triangle (Front)
InBlock.gif                        gl.Color(0.0f, 0.0f, 1.0f);         // Blue
InBlock.gif                        gl.Vertex(1.0f, -1.0f, 0.0f);         // Right Of Triangle (Front)
InBlock.gif
InBlock.gif                        gl.End();             // Done Drawing The Pyramid
InBlock.gif
InBlock.gif                        gl.Translate(3f, 0.0f, 0.0f);         // Move Right And Into The Screen
InBlock.gif                        gl.Rotate(rquad,1.0f,0.0f,0.0f); //表示其绕x轴旋转,旋转角度为rquad所代表的角度
InBlock.gif
InBlock.gif                        gl.Begin(OpenGL.QUADS);             // Start Drawing The Cube
InBlock.gif                        gl.Color(0.5f, 0.5f, 1.0f);         // Set The Color To Green
InBlock.gif                        gl.Vertex(-1.0f, 1.0f, 0.0f);         // Top Right Of The Quad (Top)
InBlock.gif                        gl.Vertex(1.0f, 1.0f, 0.0f);         // Top Left Of The Quad (Top)
InBlock.gif                        gl.Vertex(1.0f, -1.0f, 0.0f);         // Bottom Left Of The Quad (Top)
InBlock.gif                        gl.Vertex(-1.0f, -1.0f, 0.0f);         // Bottom Right Of The Quad (Top)
InBlock.gif                
InBlock.gif
InBlock.gif                        gl.End();             // Done Drawing The Q
InBlock.gif
InBlock.gif                        gl.Flush();
InBlock.gif
InBlock.gif                        rtri += 3.0f; // 0.2f;             // Increase The Rotation Variable For The Triangle    
InBlock.gif                        rquad -= 3.0f; // 0.15f;             // Decrease The Rotation Variable For The Quad    
InBlock.gif}
InBlock.gif
 

运行效果:

 
 
其旋转方式和我们想的好像不太一样,
正方形好像并不以其自身的x轴为旋转轴,却是以三角形所定位的坐标轴的x轴进行旋转!
这里主要是因为在代码中画四边形时以三角形的坐标轴为源进行了平移操作
gl.Translate(3f, 0.0f, 0.0f);     // Move Right And Into The Screen
所以旋转起来必然是相对于三角形的坐标系为轴进行旋转。
如何将三角形和正方形的旋转独立起来呢!
我们如果将两个物体的坐标系相互独立应该就可以绕其自身所定义的坐标系旋转了吧!
Nehe的教程中给出了答案。
即在画第二个物体前将坐标轴重置,恢复到系统原点。调用gl.LoadIdentity();函数。
这时如果调用gl.Translate(3f, 0.0f, 0.0f);     是相对于系统原点的平移,计算一下这时的坐标参数就不对了,应改成
gl.Translate(1.5f, 0.0f, -7.0f);    

这时的   OpenGLDraw的事件响应函数为:

 
InBlock.gif     private void openGLControl1_OpenGLDraw( object sender, PaintEventArgs e)
InBlock.gif                {
InBlock.gif
InBlock.gif                         // Get the OpenGL object, just to clean up the code.
InBlock.gif                        SharpGL.OpenGL gl = this.openGLControl1.OpenGL;
InBlock.gif
InBlock.gif                        gl.Clear(OpenGL.COLOR_BUFFER_BIT | OpenGL.DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
InBlock.gif                        gl.LoadIdentity();             // Reset The View
InBlock.gif                        gl.Translate(-1.5f, 0.0f, -6.0f);         // Move Left And Into The Screen
InBlock.gif                        
InBlock.gif                        gl.Rotate(rtri,0.0f,1.0f,0.0f);
InBlock.gif                        gl.Begin(OpenGL.TRIANGLES);             // Start Drawing The Pyramid
InBlock.gif                        gl.Color(1.0f, 0.0f, 0.0f);         // Red
InBlock.gif                        gl.Vertex(0.0f, 1.0f, 0.0f);         // Top Of Triangle (Front)
InBlock.gif                        gl.Color(0.0f, 1.0f, 0.0f);         // Green
InBlock.gif                        gl.Vertex(-1.0f, -1.0f, 0.0f);         // Left Of Triangle (Front)
InBlock.gif                        gl.Color(0.0f, 0.0f, 1.0f);         // Blue
InBlock.gif                        gl.Vertex(1.0f, -1.0f, 0.0f);         // Right Of Triangle (Front)
InBlock.gif
InBlock.gif                        gl.End();             // Done Drawing The Pyramid
InBlock.gif                     gl.LoadIdentity();
InBlock.gif                        gl.Translate(1.5f, 0.0f, -7.0f);         // Move Right And Into The Screen
InBlock.gif                        gl.Rotate(rquad,1.0f,0.0f,0.0f);
InBlock.gif
InBlock.gif                        gl.Begin(OpenGL.QUADS);             // Start Drawing The Cube
InBlock.gif                        gl.Color(0.5f, 0.5f, 1.0f);         // Set The Color To Green
InBlock.gif                        gl.Vertex(-1.0f, 1.0f, 0.0f);         // Top Right Of The Quad (Top)
InBlock.gif                        gl.Vertex(1.0f, 1.0f, 0.0f);         // Top Left Of The Quad (Top)
InBlock.gif                        gl.Vertex(1.0f, -1.0f, 0.0f);         // Bottom Left Of The Quad (Top)
InBlock.gif                        gl.Vertex(-1.0f, -1.0f, 0.0f);         // Bottom Right Of The Quad (Top)
InBlock.gif                
InBlock.gif
InBlock.gif                        gl.End();             // Done Drawing The Q
InBlock.gif
InBlock.gif                        gl.Flush();
InBlock.gif
InBlock.gif                        rtri += 3.0f; // 0.2f;             // Increase The Rotation Variable For The Triangle    
InBlock.gif                        rquad -= 3.0f; // 0.15f;             // Decrease The Rotation Variable For The Quad    
InBlock.gif                }
InBlock.gif

运行效果如下:

这时得到了符合我们的预想的方式的旋转情景。
此章节源代码  下载