OpenGl学习之钢体运动

</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),则就可以进行旋转


放缩


原点缩放


对于原点缩放,也可以使用矩阵变换来表示


通用基准点缩放


通用基准点缩放,使用下面矩阵进行变换表示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值