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

变换前的图形

一系列变换后

猜你喜欢

转载自blog.csdn.net/qq_41856733/article/details/84674185