Computer graphics and OpenGL learning five (two-dimensional geometric transformation 1. translation, rotation, scaling)

2D geometric transformations (translation, rotation, scaling)

This chapter involves a lot of mathematical transformations, the code is secondary, and the mathematical theory can be deduced by yourself.

Two-dimensional translation

A translation is achieved by adding a two-dimensional quantity to the coordinates of a point to generate a new coordinate position. The translation distance is added to the original coordinates to obtain a new coordinate , and a two-dimensional position translation is realized.

For the translation vector, if a column vector is used to represent the coordinates of each point:


Example :

Translate a quadrilateral, input the translation amount by yourself, the resulting image translation amount is (200, 200), the code:

#include<GL/glut.h>
#include<math.h>
#include<Windows.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
GLsizei winWidth = 500, winHeight = 500;
GLuint regHex;//Display table ID
class wcPt2D
{
public:
	GLfloat x, y;
	wcPt2D(GLfloat x=0,GLfloat y=0)
	{
		this->x = x;
		this->y = y;
	}
};
wcPt2D verts[4] = { wcPt2D(10.0, 20.0), wcPt2D(100.0, 50.0), wcPt2D(120, 240.0), wcPt2D (30.0,220.0)};
GLfloat tx; GLfloat ty;
void Move(wcPt2D *verts,GLfloat tx,GLfloat ty)
{
	//Translation function, as an example to translate the quad
	GLint nverts = 4;
	GLint k;
	wcPt2D newVerts[4];//Use a new vertex object set to observe the translation effect
	for (k = 0; k < nverts;++k)
	{
		newVerts[k].x = verts[k].x + tx;
		newVerts[k].y = verts[k].y + ty;
	}
	
	glBegin(GL_QUADS);
	for (k = 0; k < nverts; ++k)
	{
		glVertex2f(verts[k].x, verts[k].y);
	}
	for (k = 0; k < nverts; ++k)
	{
		glVertex2f(newVerts[k].x, newVerts[k].y);
	}
	glEnd();

	glFlush();
}
void funcPlot()
{
	glClear(GL_COLOR_BUFFER_BIT);
	Move(verts,tx,ty);
}

static void init(void)
{
	//Initialize the function and join the table

	glClearColor(1.0, 1.0, 1.0, 0.0);//Set to white background
	regHex = glGenLists(1);//Get an identity
	glColor3f(1.0, 0.0,0.0);
	glPointSize(2);
	

}



void winReshapeFcn(int newWidth, int newHeight)
{
	//window reshape function
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();//Move the origin of the current user coordinate system to the center of the screen: similar to a reset operation
	gluOrtho2D(0.0, (GLdouble)newWidth, 0.0, (GLdouble)newWidth);
	glClear(GL_COLOR_BUFFER_BIT);


} int main(int argc, char**argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowPosition (100, 100);
	glutInitWindowSize (winWidth, winHeight);
	glutCreateWindow("Example");
	cout << "Enter x,y offset (range 0-200,0-200):" << endl;
	cin >> tx >> ty;
	init();
	glutDisplayFunc(funcPlot);
	glutReshapeFunc(winReshapeFcn);
	glutMainLoop();
	return 0;
}

Result :


【Two-dimensional rotation】

By specifying a rotation axis and a rotation angle, a rotation is performed, that is, all vertices of the object are rotated around the specified rotation axis by the specified angle.

When rotating around the origin, let be the angle between the original angular position of the point and the horizontal line, which is the rotation angle. The rotated coordinates are expressed as:




Example : Enter the rotation base point for the quadrilateral of the previous example, and revolve it around the specified angle. This time the result is the base point (0,450) and the rotation angle is 45°. The code is similar to panning, only the core code is shown:

class wcPt2D
{
public:
	GLfloat x, y;
	wcPt2D(GLfloat x=0,GLfloat y=0)
	{
		this->x = x;
		this->y = y;
	}
};
wcPt2D verts[4] = { wcPt2D(10.0, 20.0), wcPt2D(100.0, 50.0), wcPt2D(120, 240.0), wcPt2D (30.0,220.0)};
GLfloat xr; GLfloat yr;//reference point
GLdouble theta;//Rotation angle
void rotate(wcPt2D *verts,GLfloat xr,GLfloat yr,GLdouble theta)
{
	//Rotation function, as an example to translate the quad
	GLint nverts = 4;
	GLint k;
	wcPt2D newVerts[4];//Use a new vertex object set to observe the translation effect
	for (k = 0; k < nverts;++k)
	{
		newVerts[k].x = xr + (verts[k].x - xr)*cos(theta) - (verts[k].y - yr)*sin(theta);
		newVerts[k].y = yr + (verts[k].x - xr)*sin(theta) + (verts[k].y - yr)*cos(theta);
	}
	
	glBegin(GL_QUADS);
	for (k = 0; k < nverts; ++k)
	{
		glVertex2f(verts[k].x, verts[k].y);
	}
	for (k = 0; k < nverts; ++k)
	{
		glVertex2f(newVerts[k].x, newVerts[k].y);
	}
	glEnd();

	glFlush();
}

Result :


【2D zoom】

To change the size of an object, use the zoom transformation. A simple 2D zoom operation can be obtained by multiplying the zoom factor sum by the object coordinate position:

When the absolute value of the zoom factor is less than 1, the zoomed object moves closer to the origin; when the absolute value of the zoom factor is greater than 1, the zoomed object moves away from the origin. We can choose a point that does not change position after scaling, called a fixed point. The fixed point is set to (xf, yf), and the scaled coordinates can be calculated as:

The equation is transformed into:




Example :

Still using the above quadrilateral, select the point in the lower left corner as the scaling base point, the scaling factor needs to be input, and the result is the effect when the scaling factor Sx, Sy=2. After zooming, I panned to the left by 200 pixels to obtain a contrast effect. The core code is as follows:


class wcPt2D
{
public:
	GLfloat x, y;
	wcPt2D(GLfloat x=0,GLfloat y=0)
	{
		this->x = x;
		this->y = y;
	}
};
wcPt2D verts[4] = { wcPt2D(10.0, 20.0), wcPt2D(100.0, 50.0), wcPt2D(120, 240.0), wcPt2D (30.0,220.0)};
GLfloat sx; GLfloat sy;//Scaling factor
void scale (wcPt2D * verts, GLfloat sx, GLfloat sy)
{
	// zoom function, as an example to translate the quad
	GLint nverts = 4;
	wcPt2D fixedPt = verts[0];//Select the lower left point as the reference point
	GLint k;
	wcPt2D newVerts[4];//Use a new vertex object set to observe the translation effect
	for (k = 0; k < nverts;++k)
	{
		newVerts[k].x = verts[k].x*sx+fixedPt.x*(1-sx)+200;//Add 200 to horizontally translate 200 pixels for easy comparison
		newVerts[k].y = verts[k].y*sy + fixedPt.y*(1 - sy);
	}
	
	glBegin(GL_QUADS);
	for (k = 0; k < nverts; ++k)
	{
		glVertex2f(verts[k].x, verts[k].y);
	}
	for (k = 0; k < nverts; ++k)
	{
		glVertex2f(newVerts[k].x, newVerts[k].y);
	}
	glEnd();

	glFlush();
}
void funcPlot()
{
	glClear(GL_COLOR_BUFFER_BIT);
	scale (verts, sx, sy);
}

result:


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324412388&siteId=291194637
Recommended