图形学技术是一门涉及计算机图形和图像处理的学科,其目标是通过算法和数学模型来创建、处理和呈现图形和图像。这项技术的应用范围非常广泛,涵盖了许多领域,包括计算机游戏、虚拟现实、计算机辅助设计(CAD)、医学图像处理、动画制作等。 以下是图形学技术的一些关键方面:
在图形学技术的发展中,硬件加速、实时渲染、虚拟现实和增强现实等方面的创新不断推动着图形学的前沿。这门技术为数字世界的可视化和交互提供了强大的工具和方法。
图形的几何变换一般是指对图形的几何信息经过变换后产生新的图形,图形几何变换既可以看作是坐标系不动而图形变动,变动后的图形在坐标系中的坐标值发生变化;出可以看作图形不动而坐标系变动,变动后的图形在新坐标系下具有新的坐标值。这两种情况本质上都是一样的,都是图形由新的坐标值表示,因此是新产生的图形。图形几何变换包括比例变换、对称变换、错切变换、旋转变换、平移变换及其复合变换。图形上所有的点在几何变换前后的坐标关系一般用解析几何方法可以求得,但这些几何关系用矩阵方法表示,运算更为方便。
图形基本几何变换是指比例变换、对称变换、错切变换、旋转变换和平移变换等。除平移变换外,这里其它四种几何变换都可以用组成图形的点向量(或称1×2阶矩阵)和2×2阶变换矩阵相乘表示,而平移变换需引入新方法来实现。
对图形分别进行平移变换、旋转变换、对称变换以及比例变换。
程序代码示例如下:
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
GLsizei winWidth = 600, winHeight = 600;
GLfloat xwcMin = 0.0, xwcMax = 225.0;
GLfloat ywcMin = 0.0, ywcMax = 225.0;
class wcPt2D
{
public:
GLfloat x, y;
};
typedef GLfloat Matrix3x3[3][3];
Matrix3x3 matComposite;
const GLdouble pi = 3.14159;
void Init()
{
glClearColor(1.0, 1.0, 1.0, 0.0);
}
void Matrix3x3SetIdentity(Matrix3x3 matIdent3x3)
{
GLint row, col;
for (row = 0; row < 3; row++)
{
for (col = 0; col < 3; col++)
{
matIdent3x3[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 TransformVerts2D(GLint nVerts, wcPt2D* verts)//平移函数实现
{
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 Trangle(wcPt2D* verts)
{
GLint k;
glBegin(GL_TRIANGLES);
for (k = 0; k < 3; k++)
{
glVertex2f(verts[k].x, verts[k].y);
}
glEnd();
}
void WinReshapFcn(GLint newWidth, GLint newHeight)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(xwcMin, xwcMax, ywcMin, ywcMax);
glClear(GL_COLOR_BUFFER_BIT);
}
void DisplayFcn()
{
glClear(GL_COLOR_BUFFER_BIT);
GLint nVerts = 3;
wcPt2D verts[3] = { {50,25},{150,25 },{100,100} };
wcPt2D centroidPt;
GLint k, xSum = 0, ySum = 0;
for (size_t 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, ty = 100;
GLfloat sx = 0.5, sy = 0.5;
GLdouble theta = pi / 2;
glColor3f(0, 0, 1);
Trangle(verts);
Matrix3x3SetIdentity(matComposite);
Translate2D(tx, ty);
TransformVerts2D(nVerts, verts);//调用函数
glColor3f(1, 0, 0);
Trangle(verts);
glFlush();
}
void draw_pixel(int ix, int iy)
{
glBegin(GL_POINTS);
glVertex2i(ix, iy);
glEnd();
}
void myinit()
{
glClearColor(1.0, 0.8, 1.0, 1.0);
glColor3f(0.0, 0.5, 0.5);
glPointSize(1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 1000.0, 0.0, 1000.0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 500);
glutInitWindowPosition(150.0, 150.0);
glutCreateWindow("图像平移变换");
glutDisplayFunc(DisplayFcn);
glutReshapeFunc(WinReshapFcn);
myinit();
glutMainLoop();
}
运行结果:
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
GLsizei winWidth = 600, winHeight = 600;
GLfloat xwcMin = 0.0, xwcMax = 225.0;
GLfloat ywcMin = 0.0, ywcMax = 225.0;
class wcPt2D
{
public:
GLfloat x, y;
};
typedef GLfloat Matrix3x3[3][3];
Matrix3x3 matComposite;
const GLdouble pi = 3.14159;
void Init()
{
glClearColor(1.0, 1.0, 1.0, 0.0);
}
void Matrix3x3SetIdentity(Matrix3x3 matIdent3x3)
{
GLint row, col;
for (row = 0; row < 3; row++)
{
for (col = 0; col < 3; col++)
{
matIdent3x3[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 TransformVerts2D(GLint nVerts, wcPt2D* verts)//平移
{
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 Trangle(wcPt2D* verts)
{
GLint k;
glBegin(GL_TRIANGLES);
for (k = 0; k < 3; k++)
{
glVertex2f(verts[k].x, verts[k].y);
}
glEnd();
}
void WinReshapFcn(GLint newWidth, GLint newHeight)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(xwcMin, xwcMax, ywcMin, ywcMax);
glClear(GL_COLOR_BUFFER_BIT);
}
void DisplayFcn()
{
GLint nVerts = 3;
wcPt2D verts[3] = { {50,25},{150,25 },{100,100} };
wcPt2D centroidPt;
GLint k, xSum = 0, ySum = 0;
for (size_t 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, ty = 100;
GLfloat sx = 0.5, sy = 0.5;
GLdouble theta = pi / 2;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0, 0, 1);
Trangle(verts);
Matrix3x3SetIdentity(matComposite);
Rotate2D(pivPt, theta);
Translate2D(tx, ty);
TransformVerts2D(nVerts, verts);
glColor3f(1, 0, 0);
Trangle(verts);
glFlush();
}
void draw_pixel(int ix, int iy)
{
glBegin(GL_POINTS);
glVertex2i(ix, iy);
glEnd();
}
void myinit()
{
glClearColor(1.0, 0.8, 1.0, 1.0);
glColor3f(0.0, 0.5, 0.5);
glPointSize(1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 1000.0, 0.0, 1000.0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 500);
glutInitWindowPosition(150.0, 150.0);
glutCreateWindow("图像旋转变换");
glutDisplayFunc(DisplayFcn);
glutReshapeFunc(WinReshapFcn);
myinit();
glutMainLoop();
}
运行结果:
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
GLsizei winWidth = 600, winHeight = 600;
GLfloat xwcMin = 0.0, xwcMax = 225.0;
GLfloat ywcMin = 0.0, ywcMax = 225.0;
class wcPt2D
{
public:
GLfloat x, y;
};
typedef GLfloat Matrix3x3[3][3];
Matrix3x3 matComposite;
const GLdouble pi = 3.14159;
void Init()
{
glClearColor(1.0, 1.0, 1.0, 0.0);
}
void Matrix3x3SetIdentity(Matrix3x3 matIdent3x3)
{
GLint row, col;
for (row = 0; row < 3; row++)
{
for (col = 0; col < 3; col++)
{
matIdent3x3[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 TransformVerts2D(GLint nVerts, wcPt2D* verts)//平移
{
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 Trangle(wcPt2D* verts)
{
GLint k;
glBegin(GL_TRIANGLES);
for (k = 0; k < 3; k++)
{
glVertex2f(verts[k].x, verts[k].y);
}
glEnd();
}
void WinReshapFcn(GLint newWidth, GLint newHeight)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(xwcMin, xwcMax, ywcMin, ywcMax);
glClear(GL_COLOR_BUFFER_BIT);
}
void DisplayFcn()
{
GLint nVerts = 3;
wcPt2D verts[3] = { {50,25},{150,25 },{100,100} };
wcPt2D centroidPt;
GLint k, xSum = 0, ySum = 0;
for (size_t 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, ty = 100;
GLfloat sx = 0.5, sy = 0.5;
GLdouble theta = pi;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0, 0, 1);
Trangle(verts);
Matrix3x3SetIdentity(matComposite);
Rotate2D(pivPt, theta);
Translate2D(tx, ty);
TransformVerts2D(nVerts, verts);
glColor3f(1, 0, 0);
Trangle(verts);
glFlush();
}
void draw_pixel(int ix, int iy)
{
glBegin(GL_POINTS);
glVertex2i(ix, iy);
glEnd();
}
void myinit()
{
glClearColor(1.0, 0.8, 1.0, 1.0);
glColor3f(0.0, 0.5, 0.5);
glPointSize(1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 1000.0, 0.0, 1000.0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 500);
glutInitWindowPosition(150.0, 150.0);
glutCreateWindow("图像对称变换");
glutDisplayFunc(DisplayFcn);
glutReshapeFunc(WinReshapFcn);
myinit();
glutMainLoop();
}
运行结果:
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
GLsizei winWidth = 600, winHeight = 600;
GLfloat xwcMin = 0.0, xwcMax = 225.0;
GLfloat ywcMin = 0.0, ywcMax = 225.0;
class wcPt2D
{
public:
GLfloat x, y;
};
typedef GLfloat Matrix3x3[3][3];
Matrix3x3 matComposite;
const GLdouble pi = 3.14159;
void Init()
{
glClearColor(1.0, 1.0, 1.0, 0.0);
}
void Matrix3x3SetIdentity(Matrix3x3 matIdent3x3)
{
GLint row, col;
for (row = 0; row < 3; row++)
{
for (col = 0; col < 3; col++)
{
matIdent3x3[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 Scale2D(GLfloat sx, GLfloat sy, wcPt2D fixedPt)//缩放
{
Matrix3x3 matScale;
Matrix3x3SetIdentity(matScale);
matScale[0][0] = sx;
matScale[0][2] = (1 - sx) * fixedPt.x;
matScale[1][1] = sy;
matScale[1][2] = (1 - sy) * fixedPt.y;
Matrix3x3PreMultiply(matScale, matComposite);
}
void TransformVerts2D(GLint nVerts, wcPt2D* verts)//平移
{
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 Trangle(wcPt2D* verts)
{
GLint k;
glBegin(GL_TRIANGLES);
for (k = 0; k < 3; k++)
{
glVertex2f(verts[k].x, verts[k].y);
}
glEnd();
}
void WinReshapFcn(GLint newWidth, GLint newHeight)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(xwcMin, xwcMax, ywcMin, ywcMax);
glClear(GL_COLOR_BUFFER_BIT);
}
void DisplayFcn()
{
GLint nVerts = 3;
wcPt2D verts[3] = { {50,25},{150,25 },{100,100} };
wcPt2D centroidPt;
GLint k, xSum = 0, ySum = 0;
for (size_t 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, ty = 100;
GLfloat sx = 0.5, sy = 0.5;
GLdouble theta = pi / 2;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0, 0, 1);
Trangle(verts);
Matrix3x3SetIdentity(matComposite);
Scale2D(sx, sy, fixedPt);
Translate2D(tx, ty);
TransformVerts2D(nVerts, verts);
glColor3f(1, 0, 0);
Trangle(verts);
glFlush();
}
void draw_pixel(int ix, int iy)
{
glBegin(GL_POINTS);
glVertex2i(ix, iy);
glEnd();
}
void myinit()
{
glClearColor(1.0, 0.8, 1.0, 1.0);
glColor3f(0.0, 0.5, 0.5);
glPointSize(1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 1000.0, 0.0, 1000.0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 500);
glutInitWindowPosition(150.0, 150.0);
glutCreateWindow("图像比例变换");
glutDisplayFunc(DisplayFcn);
glutReshapeFunc(WinReshapFcn);
myinit();
glutMainLoop();
}
运行结果:
图形学领域宛如一片广阔而未被完全探索的创意海洋,邀请你勇敢踏足数字艺术和计算机图形学的神秘领域。