• 计算机图形学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;
    }
    
    

    变换前的图形

    一系列变换后

  • 相关阅读:
    loadrunner提高篇
    loadrunner提高篇
    loadrunner提高篇
    STM32F4XX高效驱动篇1-UART
    系统封装接口层 cmsis_os
    uCGUI 按键窗口切换机制
    xming+xshell让linux变成桌面化操作
    jmeter做WebSocket请求解读
    性能监控工具spotlight操作
    linux性能监控命令,磁盘,网络,cpu,内存
  • 原文地址:https://www.cnblogs.com/vivid-victory/p/10090461.html
Copyright © 2020-2023  润新知