天天看點

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

效果就是把一個圖形進行平移旋轉和放縮之後到指定的地點

運作結果如圖所示

OpenGl學習之鋼體運動平移旋轉放縮

這個程式就是示範如何進行平移、旋轉和放縮

其實這些都是對矩陣的操作

平移

使用齊次坐标方法,坐标位置的二維平移可表示為下面的矩陣乘法

OpenGl學習之鋼體運動平移旋轉放縮

或者簡單表示為

OpenGl學習之鋼體運動平移旋轉放縮

這樣我們需要做的就是對矩陣進行指派操作之後然後矩陣相乘就行

旋轉

繞原點旋轉

繞原點也就是坐标原點進行旋轉的變換方程可以表示成

OpenGl學習之鋼體運動平移旋轉放縮

後者簡單表示成

OpenGl學習之鋼體運動平移旋轉放縮

這樣就對對矩陣進行指派操作之後然後矩陣相乘就行

繞通用二維基準點進行旋轉

給定一個固定的基準點為(xr,yr),則就可以進行旋轉

OpenGl學習之鋼體運動平移旋轉放縮

放縮

原點縮放

對于原點縮放,也可以使用矩陣變換來表示

OpenGl學習之鋼體運動平移旋轉放縮

通用基準點縮放

通用基準點縮放,使用下面矩陣進行變換表示

OpenGl學習之鋼體運動平移旋轉放縮

繼續閱讀