作业题目:
图形变换:实现一个图形绕任意直线旋转的程序。
要求:把一个三维图形绕任意一条直线旋转,需要有初始图形,和旋转后的图形,最好也可以实时控制旋转。
最少要做出绕z轴旋转。
原理:http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/ArbitraryAxisRotation.html
或参见《计算机图形学》
1: #include "stdafx.h"
2: #include<gl/glut.h> 3: #include<windows.h> 4: #include<gl/GLU.h> 5: #include<gl/GL.h> 6: #include <math.h> 7: GLfloat rtri=45,posX=1,posY=1.0,posZ=1,scale=0.5; 8: 9: void keyboard(unsigned char key,int x,int y){
10: switch (key) {
11: case 'l':
12: rtri=rtri+5;13: if(rtri>=360)
14: rtri=0.0; 15: glutPostRedisplay();16: break;
17: case 'r':
18: rtri=rtri-5;19: if(rtri<=0)
20: rtri=360; 21: glutPostRedisplay();22: break;
23: case 's':
24: scale=scale+0.1;25: if(scale>=1.0)
26: scale=0.0; 27: glutPostRedisplay();28: break;
29: case 'S':
30: scale=scale-0.1;31: if(scale<=0.0)
32: scale=1.0; 33: glutPostRedisplay();34: break;
35: case 'x':
36: posX = posX+0.1;37: if(posX>=1.0)
38: posX=0; 39: glutPostRedisplay();40: break;
41: case 'X':
42: posX = posX-0.1;43: if(posX<=0.0)
44: posY=1.0; 45: glutPostRedisplay();46: break;
47: case 'y':
48: posY = posY+0.1;49: if(posY>=1.0)
50: posY=0; 51: glutPostRedisplay();52: break;
53: case 'Y':
54: posY = posY-0.1;55: if(posY<=0.0)
56: posY=1; 57: glutPostRedisplay();58: break;
59: case 'z':
60: posZ = posZ+0.1;61: if(posZ>=1.0)
62: posZ=0; 63: glutPostRedisplay();64: break;
65: case 'Z':
66: posZ = posZ-0.1;67: if(posZ<=0.0)
68: posZ=1.0; 69: glutPostRedisplay();70: break;
71: case 27:
72: exit(0);73: break;
74: } 75: }76: void rotate_Matrix(float r,float x,float y,float z){
77: float l=sqrt(x*x+z*z);
78: float v=sqrt(y*y+z*z);
79: float sin_r1=y/v;
80: float cos_r1=z/v;
81: float sin_r2=-x/l;
82: float cos_r2=z/l;
83: GLfloat revTranslateMatrix[]= 84: { 85: 1.0f,0.0f, 0.0f,posX, 86: 0.0f,1.0f, 0.0f,posY, 87: 0.0f,0.0f, 1.0f,posZ, 88: 0.0f,0.0f, 0.0f,1.0f 89: }; 90: GLfloat translateMatrix[]= 91: { 92: 1.0f,0.0f, 0.0f,-posX, 93: 0.0f,1.0f, 0.0f,-posY, 94: 0.0f,0.0f, 1.0f,-posZ, 95: 0.0f,0.0f, 0.0f,1.0f 96: }; 97: 98: GLfloat scaleMatrix[]= 99: { 100: scale, 0.0f, 0.0f,0.0f, 101: 0.0f,scale, 0.0f, 0.0f, 102: 0.0f, 0.0f, scale, 0.0f, 103: 0.0, 0.0f, 0.0f, 1.0f 104: }; 105: GLfloat rotateXMatrix[]= 106: { 107: 1.0f,0.0f ,0.0f ,0.0f, 108: 0.0f,cos_r1,sin_r1,0.0f, 109: 0.0f,-sin_r1,cos_r1,0.0f, 110: 0.0f,0.0f ,0.0f ,1.0f 111: }; 112: GLfloat revRotateXMatrix[]= 113: { 114: 1.0f,0.0f ,0.0f ,0.0f, 115: 0.0f,cos_r1,-sin_r1,0.0f, 116: 0.0f,sin_r1,cos_r1,0.0f, 117: 0.0f,0.0f ,0.0f ,1.0f 118: }; 119: GLfloat rotateYMatrix[]= 120: { 121: cos_r2 ,0.0f,-sin_r2,0.0f, 122: 0.0f ,1.0f,0.0f ,0.0f, 123: sin_r2,0.0f,cos_r2,0.0f, 124: 0.0f ,0.0f,0.0f ,1.0f 125: }; 126: GLfloat revRotateYMatrix[]= 127: { 128: cos_r2 ,0.0f,sin_r2,0.0f, 129: 0.0f ,1.0f,0.0f ,0.0f, 130: -sin_r2,0.0f,cos_r2,0.0f, 131: 0.0f ,0.0f,0.0f ,1.0f 132: }; 133: GLfloat rotateZMatrix[]= 134: { 135: cos(r),-sin(r),0.0f,0.0f, 136: sin(r),cos(r) ,0.0f,0.0f, 137: 0.0f ,0.0f ,1.0f,0.0f, 138: 0.0f ,0.0f ,0.0f,1.0f 139: };140: //glMultMatrixf(translateMatrix);
141: glMultMatrixf(rotateXMatrix); 142: glMultMatrixf(rotateYMatrix); 143: glMultMatrixf(rotateZMatrix); 144: glMultMatrixf(revRotateYMatrix); 145: glMultMatrixf(revRotateXMatrix);146: //glMultMatrixf(revTranslateMatrix);
147: }148: void drawModel(){
149: glLineWidth(1); 150: glColor3f(1,1,1); 151: //glutWireSphere(1,20,16);
152: glutWireTeapot(0.5); 153: glLineWidth(4); 154: 155: }156: void drawAxis(float size){
157: //draw axis
158: glLineWidth(3); 159: glBegin(GL_LINES); 160: glColor3f(1.0,0,0); 161: glVertex3f(0,0,0); 162: glVertex3f(size,0,0); 163: glColor3f(0,1,0); 164: glVertex3f(0,0,0); 165: glVertex3f(0,size,0); 166: glColor3f(0,0,1); 167: glVertex3f(0,0,0); 168: glVertex3f(0,0,size); 169: glEnd(); 170: glLineWidth(1); 171: 172: //draw arrows
173: glPointSize(5); 174: glBegin(GL_POINTS); 175: glColor3f(1,0,0); 176: glVertex3f(size,0,0); 177: glColor3f(0,1,0); 178: glVertex3f(0,size,0); 179: glColor3f(0,0,1); 180: glVertex3f(0,0,size); 181: glEnd(); 182: glPointSize(1); 183: } 184: 185: void renderGL()
186: { 187: glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 188: glMatrixMode( GL_MODELVIEW ); 189: glLoadIdentity(); 190: glBegin(GL_LINES); 191: glColor3f(0.5,0.5,0.5); 192: glVertex3f(0,0,0); 193: glVertex3f(posX,posY,posZ);194: printf("x:%f y:%f z:%f ",posX,posY,posZ);
195: glEnd(); 196: drawAxis(2.5); 197: rotate_Matrix(rtri,posX,posY,posZ); 198: drawModel(); 199: glutSwapBuffers(); 200: } 201: 202: int initGL(int argc,char **argv){
203: glutInit(&argc,argv); 204: glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH); 205: glutInitWindowSize(400,400);206: int handle=glutCreateWindow("rotate my model");
207: glutDisplayFunc(renderGL); 208: glutKeyboardFunc(keyboard);209: return handle;
210: } 211: 212: int _tmain(int argc, _TCHAR* argv[])
213: {214: initGL(argc,(char**)argv);
215: glutMainLoop();216: return 0;
217: }