您的位置:首页 > 运维架构

OpenGL关于二维变换的例子

2015-07-21 10:09 507 查看
#include<GL/glut.h>

#include<cstdlib>

#include<cmath>

#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

/*初始化窗口大小*/

GLsizei winWidth = 600, winHeight = 600; /*int*/

/*设置世界坐标系*/

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; /*float 3*3 matrix*/

const GLdouble pi = 3.14159l;

void init(void)

{

/*设置显示窗口颜色为白色*/

glClearColor(1.0, 1.0, 1.0, 0.0);

}

/*构造3*3矩阵*/

void matrix3x3SetIdentity(Matrix3x3 matIdent3x3)

{

GLint row, col;

for (row = 0; row < 3; row++)

for (col = 0; col < 3; col++)

matIdent3x3[row][col] = (row == col);/*置为单位矩阵*/

}

/*m1矩阵左乘m2,结果放在m2中*/

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];/*matTemp[row][col] = m1[row][col] * m2[col][row];*/

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置为单位矩阵

matTransl[0][2] = tx;

matTransl[1][2] = ty;/*1 0 0

0 1 100

0 0 1 */

/*连接matTransl复合矩阵*/

matrix3x3PreMultiply(matTransl, matComposite);/*

0 -0.550

0.5 0225

0 01*/

}

void rotate2D(wcPt2D pivotPt, GLfloat theta)
/*旋转矩阵*/

{

Matrix3x3 matRot;

/*初始化旋转矩阵*/

matrix3x3SetIdentity(matRot);

matRot[0][0] = cos(theta);/*theta=pi/2*/

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);

/*

0 -175

1 075

0 01*/

/*连接matRot复合矩阵*/

matrix3x3PreMultiply(matRot, matComposite);/*

0 -0.550

0.5 0125

0 01*/

}

void scale2D(GLfloat sx, GLfloat sy, wcPt2D fixedPt)

{

Matrix3x3 matScale;

/*初始化扩展矩阵*/

matrix3x3SetIdentity(matScale);/*

1 00

0 10

0 01*/

matScale[0][0] = sx;

matScale[0][2] = (1 - sx)*fixedPt.x;

matScale[1][1] = sy;

matScale[1][2] = (1 - sy)*fixedPt.y;/*

0.5 00.5*100

0 0.5 0.5*50

0 0 1*/

/*连接matScale复合矩阵*/

matrix3x3PreMultiply(matScale, matComposite);/*

0.5 050

0 0.525

0 01

*/

}

/*使用复合矩阵,计算坐标转换*/

void transformVerts2D(GLint nVerts, wcPt2D *verts)

{

/*wcPt2D
verts[3] = { { 50.0, 25.0 }, { 150.0, 25.0 }, { 100.0, 100.0 } };*/

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)

{

GLint k;

glBegin(GL_TRIANGLES);

for (k = 0; k < 3; k++)

glVertex2f(verts[k].x, verts[k].y);

glEnd();

}

void displayFcn(void)

{

/*初始化三角形位置*/

GLint nVerts = 3;/*三角形*/

wcPt2D
verts[3] = { { 50.0, 25.0 }, { 150.0, 25.0 }, { 100.0, 100.0 } };/*每个角的坐标*/

/*计算三角形质心位置*/

wcPt2D
centroidPt;

GLint k, xSum = 0, ySum = 0;

/*把每个点对应的坐标相加求和除以顶点个数求质心的坐标*/

for (k = 0; k < nVerts; k++)

{

xSum += verts[k].x;/*300*/

ySum += verts[k].y;/*150*/

}

centroidPt.x = GLfloat(xSum) / GLfloat(nVerts);/*100*/

centroidPt.y = GLfloat(ySum) / GLfloat(nVerts);/*50*/

/*设置几何转换参数*/

wcPt2D
pivPt, fixedPt;

pivPt = centroidPt;/*100,50*/

fixedPt = centroidPt;/*100,50*/

GLfloat
tx = 0.0, ty = 100.0; /*x方向不动,向y正方向平移100个单位*/

GLfloat
sx = 0.5, sy = 0.5; /*缩放比例*/

GLdouble
theta = pi / 2.0; /*逆时针选装90度*/

glClear(GL_COLOR_BUFFER_BIT);/*清空显示窗口*/

glColor3f(0.0, 0.0, 1.0);/*设置初始化填充颜色*/

triangle(verts);/*蓝色三角*/

/*初始化复合矩阵*/

matrix3x3SetIdentity(matComposite);/*matComposite

1 00

0 10

0 01*/

/*构造复合矩阵*/

scale2D(sx, sy, fixedPt);/*第一次缩放转换*/

rotate2D(pivPt, theta);/*第二次旋转转换*/

translate2D(tx, ty);/*最后一次平移转换*/

/*应用复合矩阵三角定点*/

transformVerts2D(nVerts, verts);

glColor3f(1.0, 0.0, 0.0);

triangle(verts);

glFlush();

}

void winReshapeFcn(GLint newWidth, GLint newHeight)

{

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

//glViewport(0, 0, 300, 300);

gluOrtho2D(xwcMin, newWidth, ywcMin, newHeight);

glClear(GL_COLOR_BUFFER_BIT);

}

void main(int argc, char ** argv)

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

glutInitWindowPosition(200, 100);

glutInitWindowSize(winWidth, winHeight);

glutCreateWindow("Geometric Transformation Sequence");

init();

glutDisplayFunc(displayFcn);

glutReshapeFunc(winReshapeFcn);

glutMainLoop();

}

//仰天大笑出门去,我辈岂是蓬蒿人

结果



gluOrtho2D(-1.0, 1.5, -1.5, 1.5*(GLfloat)h / (GLfloat)w);

glutInitWindowSize(400, 400);//窗口大小跟坐标轴大小不是同一个单位,就像在纸上画不同大小坐标轴一样
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: