1. 程式人生 > >計算機圖形學4——Two-Dimensional Transformation(二維幾何變換)

計算機圖形學4——Two-Dimensional Transformation(二維幾何變換)

實現二維座標變換矩陣(平移,旋轉,縮放)的生成
環境:Code::Blocks 17.12
完整程式碼如下:

// ====== Computer Graphics Experiment #5 ======
// |       Two-Dimensional Transformation      |
// =============================================
//
// Requirement:
// (1) Implement functions to generate 2D transformation matrix.
// (2) Implement function to transform 2D point using
// transformation matrix. // (3) Implement functions to rotate, scale and translate objects // using keyboard. #include <windows.h> #include <GL/glut.h>//記得要配置GLUT庫 #include <math.h> #define pi 3.1415926535 // 2D point class class CPoint2D { public: float x, y; }; // 2D transformation matrix
float My2DMatrix[3][3]; // Generate translation matrix void TranslationMatrix(float tx, float ty, float M[3][3]) // tx, ty --- Translation vector { M[0][0]=1.0; M[0][1]=0.0; M[0][2]=tx; M[1][0]=0.0; M[1][1]=1.0; M[1][2]=ty; M[2][0]=0.0; M[2][1]=0.0; M[2][2]=1.0; } // Generate rotation matrix void RotationMatrix(float
theta, float M[3][3]) // theta --- Rotation angle in degree { M[0][0]=cos(theta); M[0][1]=-sin(theta); M[0][2]=0; M[1][0]=sin(theta); M[1][1]=cos(theta); M[1][2]=0; M[2][0]=0.0; M[2][1]=0.0; M[2][2]=1.0; } // Generate scaling matrix void ScalingMatrix(float sx, float sy, float M[3][3]) // sx, sy --- Scaling factors { M[0][0]=sx; M[0][1]=0.0; M[0][2]=0; M[1][0]=0.0; M[1][1]=sy; M[1][2]=0; M[2][0]=0.0; M[2][1]=0.0; M[2][2]=1.0; } // Translate void Translate(float tx, float ty) // tx, ty --- Translation vector { float M[3][3]; //T[0][0]=0.0; T[0][1]=0.0; T[0][2]=0.0; //T[1][0]=0.0; T[1][1]=0.0; T[1][2]=0.0; //T[2][0]=0.0; T[2][1]=0.0; T[2][2]=0.0; TranslationMatrix(tx, ty, M); float T[3][3]; memset(T,0,sizeof(T)); for(int i=0;i<3;i++) for(int j=0;j<3;j++) for(int k=0;k<3;k++) { T[i][j]+=M[i][k]*My2DMatrix[k][j]; } for(int i=0;i<3;i++) for(int j=0;j<3;j++) { My2DMatrix[i][j]=T[i][j]; } } // Rotate void Rotate(float theta) // theta --- Rotation angle in degree { float M[3][3]; RotationMatrix(theta,M); float T[3][3]; memset(T,0,sizeof(T)); for(int i=0;i<3;i++) for(int j=0;j<3;j++) for(int k=0;k<3;k++) { T[i][j]+=M[i][k]*My2DMatrix[k][j]; } for(int i=0;i<3;i++) for(int j=0;j<3;j++) { My2DMatrix[i][j]=T[i][j]; } // Write your code here // Multiply M to the left of My2DMatrix } // Scale void Scale(float sx, float sy) // sx, sy --- Scaling factors { float M[3][3]; ScalingMatrix(sx, sy, M); float T[3][3]; memset(T,0,sizeof(T)); for(int i=0;i<3;i++) for(int j=0;j<3;j++) for(int k=0;k<3;k++) { T[i][j]+=M[i][k]*My2DMatrix[k][j]; } for(int i=0;i<3;i++) for(int j=0;j<3;j++) { My2DMatrix[i][j]=T[i][j]; } } // Transform 2D point void Transform2DPoint(CPoint2D *p, float M[3][3], CPoint2D *q) // p --- Input point // M --- Transformation matrix // q --- Output point { q->x=M[0][0]*p->x+M[0][1]*p->y+M[0][2]; q->y=M[1][0]*p->x+M[1][1]*p->y+M[1][2]; } void IdentityMatrix(float M[3][3]) { M[0][0]=1.0; M[0][1]=0.0; M[0][2]=0.0; M[1][0]=0.0; M[1][1]=1.0; M[1][2]=0.0; M[2][0]=0.0; M[2][1]=0.0; M[2][2]=1.0; } // Initialization function void init(void) { glClearColor (0.0, 0.0, 0.5, 0.0); IdentityMatrix(My2DMatrix); } // Display callback function void display(void) { static CPoint2D MyObject[]= {{0.0, 63.0}, {-60.0, 20.0}, {-60.0, -20.0}, {60.0, -20.0}, {60.0, 20.0}}; CPoint2D pp; int i; glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); for (i=0; i<5; ++i) { Transform2DPoint(MyObject+i, My2DMatrix, &pp); glVertex2f(pp.x, pp.y); } glEnd(); glutSwapBuffers(); } // Reshape callback function void reshape(int w, int h) { glViewport (0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-100, 100, -100, 100); } // Keyboard callback function void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); case '+': Scale(1.5,1.5);glutPostRedisplay(); break; case '-': Scale(0.75,0.75);glutPostRedisplay(); break; } } // Special keyboard callback function void special_key(int key, int x, int y) { switch (key) { case GLUT_KEY_LEFT: Translate(-5.0, 0.0);glutPostRedisplay(); break; case GLUT_KEY_RIGHT: Translate(5.0, 0.0);glutPostRedisplay(); break; case GLUT_KEY_DOWN: Translate(0.0, -5.0);glutPostRedisplay(); break; case GLUT_KEY_UP: Translate(0.0, 5.0);glutPostRedisplay(); break; // Add your code for rotation and scaling case GLUT_KEY_PAGE_UP: Scale(2,2);glutPostRedisplay(); break; case GLUT_KEY_PAGE_DOWN: Scale(0.5,0.5);glutPostRedisplay(); break; case GLUT_KEY_HOME: Rotate(pi/2);glutPostRedisplay(); break; case GLUT_KEY_END: Rotate(-pi/2);glutPostRedisplay(); break; case GLUT_KEY_INSERT: Rotate(pi);glutPostRedisplay(); break; } } // Main program entrance int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow ("Test 2D Transformation"); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutSpecialFunc(special_key); glutMainLoop(); return 0; }

變換前的圖形

一系列變換後