
平移、旋转、缩放的实现
#include<iostream>
#include <math.h>
#include<Windows.h>
#include <GL/glut.h> using namespace std; GLsizei winWidth = , winHeight = ; GLfloat xwcMin = 0.0, xwcMax = 225.0;
GLfloat ywcMin = 0.0, ywcMax = 225.0; class wcPt2D {
public:
GLfloat x, y;
}; typedef GLfloat Matrix3x3[][]; 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 = ; row < ; row++) {
for (col = ; col < ; col++) {
matIdent3x3[row][col] = (row == col);
}
}
} void matrix3x3PreMultiply(Matrix3x3 m1, Matrix3x3 m2)
{
GLint row, col;
Matrix3x3 matTemp; for (row = ; row < ; row++) {
for (col = ; col < ; col++) {
matTemp[row][col] = m1[row][] * m2[][col] + m1[row][] * m2[][col] +
m1[row][] * m2[][col];
}
} for (row = ; row < ; row++) {
for (col = ; col < ; col++) {
m2[row][col] = matTemp[row][col];
}
}
} void translate2D(GLfloat tx, GLfloat ty)
{
Matrix3x3 matTransl; matrix3x3SetIdentity(matTransl); matTransl[][] = tx;
matTransl[][] = ty; matrix3x3PreMultiply(matTransl, matComposite);
} void rotate2D(wcPt2D pivotPt, GLfloat theta)
{
Matrix3x3 matRot; matrix3x3SetIdentity(matRot); matRot[][] = cos(theta);
matRot[][] = -sin(theta);
matRot[][] = pivotPt.x * ( - cos(theta)) + pivotPt.y * sin(theta);
matRot[][] = sin(theta);
matRot[][] = cos(theta);
matRot[][] = pivotPt.y * ( - cos(theta)) - pivotPt.x * sin(theta); matrix3x3PreMultiply(matRot, matComposite);
} void scale2D(GLfloat sx, GLfloat sy, wcPt2D fixedPt)
{
Matrix3x3 matScale; matrix3x3SetIdentity(matScale); matScale[][] = sx;
matScale[][] = ( - sx) * fixedPt.x;
matScale[][] = sy;
matScale[][] = ( - sy) * fixedPt.y; matrix3x3PreMultiply(matScale, matComposite);
} void transformVerts2D(GLint nVerts, wcPt2D * verts)
{
GLint k;
GLfloat temp; for (k = ; k < nVerts; k++) {
temp = matComposite[][] * verts[k].x + matComposite[][] * verts[k].y + matComposite[][];
verts[k].y = matComposite[][] * verts[k].x + matComposite[][] * verts[k].y + matComposite[][];
verts[k].x = temp;
}
} void triangle(wcPt2D *verts)
{
glBegin(GL_TRIANGLES);
for (GLint k = ; k < ; k++) {
glVertex2f(verts[k].x, verts[k].y);
}
glEnd();
} void displayFcn()
{
GLint nVerts = ; wcPt2D verts[] = { {50.0,25.0},{150.0,25.0},{100.0,100.0} }; wcPt2D centroidPt; GLint xSum = , ySum = ; for (GLint k = ; 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 / ; 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(, ); glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("二维几何变换");
init();
glutDisplayFunc(displayFcn);
glutReshapeFunc(winReshapeFcn);
glutMainLoop(); system("pause");
return ;
}
运行结果