3.8 一些组合变换的例子
来源:互联网 发布:ubuntu 16.04 unity 编辑:程序博客网 时间:2024/04/29 15:22
这一小节主要是两个例子:创建太阳系模型,创建机器人手臂。
这两个例子,主要用来讲解如何对视图模型进行变换。
3.8.1 创建太阳系模型
/** planet.c* This program shows how to composite modeling transformations* to draw translated and rotated models.* Interaction: pressing the d and y keys (day and year)* alters the rotation of the planet around the sun.*/#include <GL/glut.h>#include <stdlib.h>static int year = 0, day = 0;void init(void){ glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT);}void display(void){ glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glPushMatrix(); glutWireSphere(1.0, 20, 16); /* draw sun */ glRotatef((GLfloat)year, 0.0, 1.0, 0.0); glTranslatef(2.0, 0.0, 0.0); glRotatef((GLfloat)day, 0.0, 1.0, 0.0); glutWireSphere(0.2, 10, 8); /* draw smaller planet */ glPopMatrix(); glutSwapBuffers();}void reshape(int w, int h){ glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 1.0, 20.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);}/* ARGSUSED1 */void keyboard(unsigned char key, int x, int y){ switch (key) { case 'd': day = (day + 10) % 360; glutPostRedisplay(); break; case 'D': day = (day - 10) % 360; glutPostRedisplay(); break; case 'y': year = (year + 5) % 360; glutPostRedisplay(); break; case 'Y': year = (year - 5) % 360; glutPostRedisplay(); break; case 27: exit(0); break; default: break; }}int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0;}
上述程序,按住字母d键,小球就会自己旋转,按住字母y键,小球就会绕太阳旋转。
主要代码如下:
glutWireSphere(1.0, 20, 16); /* draw sun */ glRotatef((GLfloat)year, 0.0, 1.0, 0.0); glTranslatef(2.0, 0.0, 0.0); glRotatef((GLfloat)day, 0.0, 1.0, 0.0); glutWireSphere(0.2, 10, 8); /* draw smaller planet */
先绘制一个太阳。接下来,有3个操作,旋转,平移,旋转。根据之前的学习,最先作用于物体的是 最后一个旋转,即day对应的旋转,绕着y轴(0.0, 1.0, 0.0),这相当于一个物体本身旋转day度, 接着平移,这个物体沿x方向平移2个单位,最后又旋转,这个物体绕原点(即太阳所在的点)旋转,旋转角度为year,旋转轴为y轴。这样就有了我们看到的效果了。
3.8.2 创建机器人手臂
/* * robot.c * This program shows how to composite modeling transformations * to draw translated and rotated hierarchical models. * Interaction: pressing the s and e keys (shoulder and elbow) * alters the rotation of the robot arm. */#include <GL/glut.h>#include <stdlib.h>static int shoulder = 0, elbow = 0;void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT);}void display(void){ glClear (GL_COLOR_BUFFER_BIT); glPushMatrix(); glTranslatef (-1.0, 0.0, 0.0); glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0); glTranslatef (1.0, 0.0, 0.0); glPushMatrix(); glScalef (2.0, 0.4, 1.0); glutWireCube (1.0); glPopMatrix(); glTranslatef (1.0, 0.0, 0.0); glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0); glTranslatef (1.0, 0.0, 0.0); glPushMatrix(); glScalef (2.0, 0.4, 1.0); glutWireCube (1.0); glPopMatrix(); glPopMatrix(); glutSwapBuffers();}void reshape (int w, int h){ glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef (0.0, 0.0, -5.0);}/* ARGSUSED1 */void keyboard (unsigned char key, int x, int y){ switch (key) { case 's': shoulder = (shoulder + 5) % 360; glutPostRedisplay(); break; case 'S': shoulder = (shoulder - 5) % 360; glutPostRedisplay(); break; case 'e': elbow = (elbow + 5) % 360; glutPostRedisplay(); break; case 'E': elbow = (elbow - 5) % 360; glutPostRedisplay(); break; case 27: exit(0); break; default: break; }}int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0;}
这段代码的运行效果如下:
按下S旋转整个手臂,按下E键旋转前半段手臂。
主要代码是绘制第一段手臂和第二段手臂。
第一段手臂
glTranslatef(-1.0, 0.0, 0.0); glRotatef((GLfloat)shoulder, 0.0, 0.0, 1.0); glTranslatef(1.0, 0.0, 0.0); glPushMatrix(); glScalef(2.0, 0.4, 1.0); glutWireCube(1.0); glPopMatrix();
同样的道理,最后出现的操作,最先作用于物体。最先是对物体进行缩放,glScalef(2.0, 0.4, 1.0), x,y,z方向,分别缩放2.0, 0.4, 1.0这样,glutWireCube就不再是一个立方体了,而变成了长方体。然后这个缩放,由于是放在glPushMatrix和glPopMatrix中,所以,缩放不对原来的坐标系产生影响。
然后,glTranslatef(1.0, 0.0, 0.0);这个长方体,进行平移,向x轴方向平移一个单位,这样的话,坐标原点就位于长方体的左端了。如下图所示。刚开始,坐标原点位于长方体中心,现在,由于物体向右平移了一个单位,所以原点位于长方体左端。
接着,glRotatef((GLfloat)shoulder, 0.0, 0.0, 1.0); 物体绕经过原点的z轴旋转shoulder度,由于z轴指向屏幕外,所以旋转之后的结果就是这样的。
最后,glTranslatef(-1.0, 0.0, 0.0); 又对物体进行移动,沿x轴移动-1.0个单位,所以其实就是将坐标系原点,又移回物体中心。
第二段手臂
glTranslatef(1.0, 0.0, 0.0); glRotatef((GLfloat)elbow, 0.0, 0.0, 1.0); glTranslatef(1.0, 0.0, 0.0); glPushMatrix(); glScalef(2.0, 0.4, 1.0); glutWireCube(1.0); glPopMatrix();
同样的,先对物体进行缩放,得到一个长方体。
然后将物体沿x轴平移一个单位,相对于这个物体的坐标原点移动到了物体的左端。
然后在旋转elbow角度,绕z轴,这个原理和第一个一样的。
最后再平移一个单位,这个其实就是将第二个物体的坐标原点,移动到和第一个物体坐标原点重合的位置。
好了,其他就没啥了。
- 3.8 一些组合变换的例子
- JAVA - 组合的例子
- 矩阵堆栈的操作、组合变换
- DCT变换的一些知识
- DCT 变换的一些思考
- 一些简单的图像变换
- 一个基本的傅立叶变换例子
- OpenGL关于二维变换的例子
- JavaScript的一些例子
- MemoryStream 的一些例子
- HTML的一些例子。
- 一些luaqt的例子
- crontab 的一些例子
- 递归的一些例子
- 缓冲区的一些例子
- shell的一些例子
- scala的一些例子
- 关于小波变换和Gabor变换的一些知识
- hihoCoder 1096 Divided Product 微软苏州校招笔试 12月27日
- 网页的初步认识
- 在CStatic静态文本框中,显示位图,控制位图大小
- android环境
- linux中文乱码,字符集和编码
- 3.8 一些组合变换的例子
- 为函数原型编写函数定义:int my_strcmp(char *s,char *t);
- 最小二乘法拟合直线
- node.js学习笔记之安装详解
- hdu 1540 Tunnel Warfare 一个关于线段的故事~~~线段树是我无法言明的伤~
- android
- 第二章第6题
- h264解码时的AVCDecoderConfigurationRecord 与 CodecPrivateData
- HDU 1501 Zipper (DFS)