Fork me on GitHub

图形学--图形几何变换

二维图形基本几何变换是指相对于坐标原点和坐标轴进行的几何变换,包括平移(Translate)、比例(Scale)、旋转(Rotate)、反射(Reflect)和错切(shear)5种变换。物体变换物体变换是通过变换物体上每一个顶点实现的,因此以点的二维基本几何变换为例讲解二维图形基本几何变换矩阵。


下面给出C++实现二维图形基本几何变换的具体代码。算法中只包含平移旋转两种变换。使用时,直接调用函数translationwhirling 即可。
读者若有其他变换需求,只需模仿这两种变换,将变换矩阵的值进行修改即可。

MatrixTransformation.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class MatrixTransformation
{
public:
MatrixTransformation();
~MatrixTransformation();

private:
int row;//矩阵行数
int column;//矩阵列数
double* pointMatrix;//点矩阵

double transforMatrix[3][3];//变换矩阵

public:
MatrixTransformation(CPoint points[], int pointNumber);

private:
bool setMatrixElement(int row, int column, double value);
bool setMatrixElement(int row, int column, double value, double matrix[]);

double getMatrixElement(int row, int column);
double getMatrixElement(int row, int column, double matrix[]);

bool setTransforMatrixElement(int row, int column, double value);

void matrixMultiplication();

public:
CPoint* matrixToPoint(CPoint points[], int point_number);//矩阵转为点数组
void translation(int offset_x, int offset_y);//平移
void whirling(double angle);//旋转
void whirling(int offset_x, int offset_y, double angle);//绕点(offset_x, offset_y)旋转
};

MatrixTransformation.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
MatrixTransformation::MatrixTransformation()
{
row = 0;
column = 0;
pointMatrix = NULL;
}
MatrixTransformation::MatrixTransformation(CPoint points[], int pointNumber)
{
row = pointNumber;
column = 3;
pointMatrix = new double[row * column];

for(int i = 1; i <= row; i++)
{
setMatrixElement(i, 1, points[i - 1].x);
setMatrixElement(i, 2, points[i - 1].y);
setMatrixElement(i, 3, 1);
}
}

MatrixTransformation::~MatrixTransformation()
{
delete[] pointMatrix;
}

bool MatrixTransformation::setMatrixElement(int row, int column, double value)
{
return setMatrixElement(row, column, value, pointMatrix);
}

bool MatrixTransformation::setMatrixElement(int row, int column, double value, double matrix[])
{
int realIndex = (row - 1) * this->column + column - 1;
if (realIndex < this->row * this->column && realIndex >= 0)
{
matrix[realIndex] = value;
return true;
}

return false;
}

double MatrixTransformation::getMatrixElement(int row, int column)
{
return getMatrixElement(row, column, pointMatrix);
}

double MatrixTransformation::getMatrixElement(int row, int column, double matrix[])
{
int realIndex = (row - 1) * this->column + column - 1;
if (realIndex < this->row * this->column && realIndex >= 0)
{
return matrix[realIndex];
}
return 0;
}

bool MatrixTransformation::setTransforMatrixElement(int row, int column, double value)
{
if (row <= 3 && row > 0 && column <= 3 && column > 0)
{
transforMatrix[row - 1][column - 1] = value;
return true;
}

return false;
}

void MatrixTransformation::matrixMultiplication()
{
double* result = new double[row * column];
int tempResult;
for (int m = 0; m < row; m++)
{
for (int s = 0; s < column; s++)
{
tempResult = 0; //变量使用前初始化,否则结果具有不确定性
for (int n = 0; n < column; n++)
{
tempResult += getMatrixElement(m + 1, n + 1) * transforMatrix[n][s];
}
setMatrixElement(m + 1, s + 1, tempResult, result);
}
}

double* tempPointer = this->pointMatrix;
this->pointMatrix = result;
delete[] tempPointer;
}

CPoint* MatrixTransformation::matrixToPoint(CPoint points[], int point_number)
{
for(int i = 1; i <= point_number; i++)
{
points[i - 1].x = getMatrixElement(i, 1);
points[i - 1].y = getMatrixElement(i, 2);
}
return points;
}

void MatrixTransformation::translation(int offset_x, int offset_y)
{
setTransforMatrixElement(1, 1, 1);
setTransforMatrixElement(1, 2, 0);
setTransforMatrixElement(1, 3, 0);
setTransforMatrixElement(2, 1, 0);
setTransforMatrixElement(2, 2, 1);
setTransforMatrixElement(2, 3, 0);
setTransforMatrixElement(3, 1, offset_x);
setTransforMatrixElement(3, 2, offset_y);
setTransforMatrixElement(3, 3, 1);

matrixMultiplication();
}

void MatrixTransformation::whirling(double angle)
{
setTransforMatrixElement(1, 1, cos(angle));
setTransforMatrixElement(1, 2, sin(angle));
setTransforMatrixElement(1, 3, 0);
setTransforMatrixElement(2, 1, -sin(angle));
setTransforMatrixElement(2, 2, cos(angle));
setTransforMatrixElement(2, 3, 0);
setTransforMatrixElement(3, 1, 0);
setTransforMatrixElement(3, 2, 0);
setTransforMatrixElement(3, 3, 1);

matrixMultiplication();
}

void MatrixTransformation::whirling(int offset_x, int offset_y, double angle)
{
translation(-offset_x, -offset_y);
whirling(angle);
translation(offset_x, offset_y);
}
扫描二维码,拯救贫困山区大学生!
-------------本文结束感谢您的阅读-------------