二维几何变换(平移、旋转、缩放)
实验要求:
- 对一个四边形进行平移,平移量自己输入,比如图平移量为(200,200)
- 将上个例子的四边形,输入旋转基点,绕指定角度。本次结果为基点(0,450),旋转角度45°
- 依然用上面的四边形,选择左下角的点作为缩放基点,缩放系数需要输入,结果是缩放系数Sx,Sy=2时的效果。缩放后进行了200像素的向左平移,以获得对比效果。
算法实现
平移(100 100):
#include<GL/glut.h>
#include<math.h>
#include<Windows.h>
#include
#include<stdlib.h>
using namespace std;
GLsizei winWidth = 500, winHeight = 500;
GLuint regHex;//显示表标识
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)
{ //平移函数,作为例子平移四边形
GLint nverts = 4;
GLint k;
wcPt2D newVerts[4];//使用一个新的顶点对象集,方便观察平移效果
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)
{//初始化函数,并加入表
glClearColor(1.0, 1.0, 1.0, 0.0);//设置为白色背景
regHex = glGenLists(1);//获得一个标识
glColor3f(1.0, 0.0,0.0);
glPointSize(2);
}
void winReshapeFcn(int newWidth, int newHeight)
{//窗口重定形函数
glMatrixMode(GL_PROJECTION);
glLoadIdentity();//将当前的用户坐标系的原点移到了屏幕中心:类似于一个复位操作
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(“Translation”);
cout << “输入x,y偏移量(范围为0-200,0-200):” << endl;
cin >> tx >> ty;
init();
glutDisplayFunc(funcPlot);
glutReshapeFunc(winReshapeFcn);
glutMainLoop();
return 0;
}
旋转(0 400 500):
#include<GL/glut.h>
#include<math.h>
#include<Windows.h>
#include
#include<stdlib.h>
using namespace std;
GLsizei winWidth = 500, winHeight = 500;
GLuint regHex;//显示表标识
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;//基准点
GLdouble theta;//旋转角度
void rotate(wcPt2D *verts,GLfloat xr,GLfloat yr,GLdouble theta)
{//旋转函数,作为例子平移四边形
GLint nverts = 4;
GLint k;
wcPt2D newVerts[4];//使用一个新的顶点对象集,方便观察平移效果
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();
}
void funcPlot()
{
glClear(GL_COLOR_BUFFER_BIT);
rotate(verts,xr,yr,theta);
}
static void init(void)
{//初始化函数,并加入表
glClearColor(1.0, 1.0, 1.0, 0.0);//设置为白色背景
regHex = glGenLists(1);//获得一个标识
glColor3f(1.0, 0.0,0.0);
glPointSize(2);
}
void winReshapeFcn(int newWidth, int newHeight)
{//窗口重定形函数
glMatrixMode(GL_PROJECTION);
glLoadIdentity();//将当前的用户坐标系的原点移到了屏幕中心:类似于一个复位操作
gluOrtho2D(0.0, (GLdouble)newWidth, 0.0, (GLdouble)newWidth);
// gluOrtho2D(-200, (GLdouble)newWidth, -200, (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(“Spin”);
cout << “旋转基准点:” << endl;
cin >> xr>>yr;
cout << “旋转角度(范围为0-2pi):” << endl;
cin >> theta;
init();
glutDisplayFunc(funcPlot);
glutReshapeFunc(winReshapeFcn);
glutMainLoop();
return 0;
}
缩放(2 2):
#include<GL/glut.h>
#include<math.h>
#include<Windows.h>
#include
#include<stdlib.h>
using namespace std;
GLsizei winWidth = 500, winHeight = 500;
GLuint regHex;//显示表标识
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;//缩放系数
void scale(wcPt2D verts,GLfloat sx,GLfloat sy)
{
//缩放函数,作为例子平移四边形
GLint nverts = 4;
wcPt2D fixedPt = verts[0];//选择左下的点作为基准点
GLint k;
wcPt2D newVerts[4];//使用一个新的顶点对象集,方便观察平移效果
for (k = 0; k < nverts;++k)
{ newVerts[k].x = verts[k].xsx+fixedPt.x*(1-sx)+200;//加200是为了水平平移200个像素,方便比较
newVerts[k].y = verts[k].ysy + 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);
}
static void init(void)
{
//初始化函数,并加入表
glClearColor(1.0, 1.0, 1.0, 0.0);//设置为白色背景
regHex = glGenLists(1);//获得一个标识
glColor3f(1.0, 0.0,0.0);
glPointSize(2);
}
void winReshapeFcn(int newWidth, int newHeight)
{//窗口重定形函数
glMatrixMode(GL_PROJECTION);
glLoadIdentity();//将当前的用户坐标系的原点移到了屏幕中心:类似于一个复位操作
gluOrtho2D(0.0, (GLdouble)newWidth, 0.0, (GLdouble)newWidth);
// gluOrtho2D(-200, (GLdouble)newWidth, -200, (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(“Zoom”);
cout << “长宽缩放因子:” << endl;
cin >> sx>>sy;
init();
glutDisplayFunc(funcPlot);
glutReshapeFunc(winReshapeFcn);
glutMainLoop();
return 0;
}
实验结果(效果图)
- 平移
- 旋转
- 缩放
心得
二维几何进行平移时,将坐标加上平移量实现平移;二维几何进行旋转时,首先输入旋转基点,按指定角度进行旋转;二维几何进行缩放时,输入缩放系数,缩放后进行200像素平移。
旋转和缩放的代码只需在平移的代码上更改部分函数,此次实验使我学习掌握了新的知识,对计算机图形的处理有了新的掌握,同时也提高了我的编程能力,对我有很大的帮助。