</pre><pre code_snippet_id="468946" snippet_file_name="blog_20140915_1_6722064" name="code" class="cpp">
刚体运动
#include <gl/glut.h>
#include <math.h>
#include <stdlib.h>
#include <GL/gl.h>
GLsizei winWidth = 600,winHeight = 600;
GLfloat xwcmin = 0.0;
GLfloat ywcmax = 225.0;
GLfloat xwcmax = 255.0;
GLfloat ywxmin = 0.0;
class wcPt2d{
public:
GLfloat x,y;
};
typedef GLfloat matrix3x3[3][3];
matrix3x3 matComposite;
const GLdouble pi = 3.1415f;
void inti()
{
glClearColor(0.0,0.0,0.0,0.0);
}
void matrix3x3setIdentity(matrix3x3 matIden3x3)//矩阵的初始化
{
GLint row,col;
//matrix3x3 matTemp;
for (row = 0;row < 3;row++)
{
for(col = 0;col < 3;col++)
{
matIden3x3[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 matSca;
matrix3x3setIdentity(matSca);
matSca[0][0] = sx;
matSca[0][2] = fixedPt.x*(1-sx);
matSca[1][1] = sy;
matSca[1][2] = fixedPt.y*(1-sy);
matrix3x3PreMultiply(matSca,matComposite);
}
void transformVerts2D(GLint nVerts,wcPt2d *verts)//利用matComposite矩阵,计算转移的坐标
{
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 display()
{
GLint nverts = 3;
wcPt2d verts[3] = {{50,25},{150,25},{100,100}};
wcPt2d centroidPt;
GLint k,xsum = 0,ysum = 0;
for(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;
GLfloat sx = 0.5,sy = 0.5;
GLdouble theta = pi/2.0;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
triangle(verts);
matrix3x3setIdentity(matComposite);
scale2D(sx,sy,fixedPt);
rotate2D(pivPt,theta);
translate2D(tx,ty);
transformVerts2D(nverts,verts);
glColor3f(1.0,0.0,0.0);
triangle(verts);
glFlush();
}
void reshape(int w,int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(xwcmin,xwcmax,ywxmin,ywcmax);
glClear(GL_COLOR_BUFFER_BIT);
}
int main(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(200,200);
glutCreateWindow("hello");
inti();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
效果就是把一个图形进行平移旋转和放缩之后到指定的地点
运行结果如图所示
这个程序就是演示如何进行平移、旋转和放缩
其实这些都是对矩阵的操作
平移
使用齐次坐标方法,坐标位置的二维平移可表示为下面的矩阵乘法
或者简单表示为
这样我们需要做的就是对矩阵进行赋值操作之后然后矩阵相乘就行
旋转
绕原点旋转
绕原点也就是坐标原点进行旋转的变换方程可以表示成
后者简单表示成
这样就对对矩阵进行赋值操作之后然后矩阵相乘就行
绕通用二维基准点进行旋转
给定一个固定的基准点为(xr,yr),则就可以进行旋转
放缩
原点缩放
对于原点缩放,也可以使用矩阵变换来表示
通用基准点缩放
通用基准点缩放,使用下面矩阵进行变换表示