OpenGL——二维几何变换
平移、旋转、缩放的实现
#include<iostream> #include <math.h> #include<Windows.h> #include <GL/glut.h> using namespace std; GLsizei winWidth = 600, winHeight = 600; GLfloat xwcMin = 0.0, xwcMax = 225.0; GLfloat ywcMin = 0.0, ywcMax = 225.0; class wcPt2D { public: GLfloat x, y; }; typedef GLfloat Matrix3x3[3][3]; Matrix3x3 matComposite; const GLdouble pi = 3.14159; void init() { //窗口背景为白色 glClearColor(1.0, 1.0, 1.0, 0.0); } void matrix3x3SetIdentity(Matrix3x3 matIdent3x3) { GLint row, col; for (row = 0; row < 3; row++) { for (col = 0; col < 3; col++) { matIdent3x3[row][col] = (row == col); } } } void matrix3x3PreMultiply(Matrix3x3 m1, Matrix3x3 m2) { GLint row, col; Matrix3x3 matTemp; for (row = 0; row < 3; row++) { for (col = 0; col < 3; col++) { matTemp[row][col] = m1[row][0] * m2[0][col] + m1[row][1] * m2[1][col] + m1[row][2] * m2[2][col]; } } for (row = 0; row < 3; row++) { for (col = 0; col < 3; col++) { m2[row][col] = matTemp[row][col]; } } } void translate2D(GLfloat tx, GLfloat ty) { Matrix3x3 matTransl; matrix3x3SetIdentity(matTransl); matTransl[0][2] = tx; matTransl[1][2] = ty; matrix3x3PreMultiply(matTransl, matComposite); } void rotate2D(wcPt2D pivotPt, GLfloat theta) { Matrix3x3 matRot; matrix3x3SetIdentity(matRot); matRot[0][0] = cos(theta); matRot[0][1] = -sin(theta); matRot[0][2] = pivotPt.x * (1 - cos(theta)) + pivotPt.y * sin(theta); matRot[1][0] = sin(theta); matRot[1][1] = cos(theta); matRot[1][2] = pivotPt.y * (1 - cos(theta)) - pivotPt.x * sin(theta); matrix3x3PreMultiply(matRot, matComposite); } void scale2D(GLfloat sx, GLfloat sy, wcPt2D fixedPt) { Matrix3x3 matScale; matrix3x3SetIdentity(matScale); matScale[0][0] = sx; matScale[0][2] = (1 - sx) * fixedPt.x; matScale[1][1] = sy; matScale[1][2] = (1 - sy) * fixedPt.y; matrix3x3PreMultiply(matScale, matComposite); } void transformVerts2D(GLint nVerts, wcPt2D * verts) { GLint k; GLfloat temp; for (k = 0; k < nVerts; k++) { temp = matComposite[0][0] * verts[k].x + matComposite[0][1] * verts[k].y + matComposite[0][2]; verts[k].y = matComposite[1][0] * verts[k].x + matComposite[1][1] * verts[k].y + matComposite[1][2]; verts[k].x = temp; } } void triangle(wcPt2D *verts) { glBegin(GL_TRIANGLES); for (GLint k = 0; k < 3; k++) { glVertex2f(verts[k].x, verts[k].y); } glEnd(); } void displayFcn() { GLint nVerts = 3; wcPt2D verts[3] = { {50.0,25.0},{150.0,25.0},{100.0,100.0} }; wcPt2D centroidPt; GLint xSum = 0, ySum = 0; for (GLint k = 0; k < nVerts; k++) { xSum += verts[k].x; ySum += verts[k].y; } centroidPt.x = GLfloat(xSum) / GLfloat(nVerts); centroidPt.y = GLfloat(ySum) / GLfloat(nVerts); wcPt2D pivPt, fixedPt; pivPt = centroidPt; fixedPt = centroidPt; GLfloat tx = 0.0, ty = 100.0; GLfloat sx = 0.5, sy = 0.5; GLdouble theta = pi / 2; glClear(GL_COLOR_BUFFER_BIT); glColor3f(200.0 / 255.0, 200.0 / 255.0, 169.0 / 255.0); triangle(verts); matrix3x3SetIdentity(matComposite); scale2D(sx, sy, fixedPt); transformVerts2D(nVerts, verts); glColor3f(137.0 / 255.0, 190.0 / 255.0, 178.0 / 255.0); triangle(verts); matrix3x3SetIdentity(matComposite); rotate2D(pivPt, theta); transformVerts2D(nVerts, verts); glColor3f(69.0 / 255.0, 137.0 / 255.0, 148.0 / 255.0); triangle(verts); matrix3x3SetIdentity(matComposite); translate2D(tx, ty); transformVerts2D(nVerts, verts); glColor3f(178.0 / 255.0, 200.0 / 255.0, 187.0 / 255.0); triangle(verts); glFlush(); } void winReshapeFcn(GLint newWidth, GLint newHeight) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(xwcMin, xwcMax, ywcMin, ywcMax); glClear(GL_COLOR_BUFFER_BIT); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); glutInitWindowPosition(50, 50); glutInitWindowSize(winWidth, winHeight); glutCreateWindow("二维几何变换"); init(); glutDisplayFunc(displayFcn); glutReshapeFunc(winReshapeFcn); glutMainLoop(); system("pause"); return 0; }
运行结果