Fork me on GitHub

图形学--3D图形斜投影

平行投影分为正投影和斜投影。
当投影线与投影面不垂直,也就是说,投影线与投影面相倾斜时,所得到的物体的投影叫做斜投影。

利用矩阵变换同样可以得到3D图形几何变换,我将图形学–图形几何变换一文中的矩阵类进行修改,再加上重写了一个CPoint3D类,就可以简单实现3D图形的 斜等测轴测投影图斜二测轴测投影图

使用时,直接调用函数 CPoint3D::cavalier_projectionCPoint3D::cabinet_projection 即可。

读者若有其他变换需求,只需模仿这两种变换,将变换矩阵的值进行修改即可。

CPoint3D.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
#pragma once
class CPoint3D
{
public:
CPoint3D();
~CPoint3D();
CPoint3D(int x, int y, int z);
private:
int x;
int y;
int z;

public:
void setX(int value);
int getX();
void setY(int value);
int getY();
void setZ(int value);
int getZ();

static void CPoint3DToCPoint(CPoint3D points_3d[], CPoint points[], int point_number);

static void cavalier_projection(CPoint3D points_3d[], CPoint points[], int point_number);//斜等测轴测投影图
static void cabinet_projection(CPoint3D points_3d[], CPoint points[], int point_number); //斜二测轴测投影图
};

CPoint3D.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
#include "stdafx.h"
#include "CPoint3D.h"
#include "MatrixTransformation3D.h"


CPoint3D::CPoint3D()
{
this->x = 0;
this->y = 0;
this->z = 0;
}


CPoint3D::~CPoint3D()
{
}
CPoint3D::CPoint3D(int x, int y, int z)
{
this->x = x;
this->y = y;
this->z = z;
}

void CPoint3D::setX(int value)
{
this->x = value;
}

int CPoint3D::getX()
{
return x;
}

void CPoint3D::setY(int value)
{
this->y = value;
}

int CPoint3D::getY()
{
return y;
}

void CPoint3D::setZ(int value)
{
this->z = value;
}

int CPoint3D::getZ()
{
return z;
}

void CPoint3D::CPoint3DToCPoint(CPoint3D points_3d[], CPoint points[], int point_number)
{
for(int i = 0; i < point_number; i++)
{
points[i].x = points_3d[i].getX();
points[i].y = points_3d[i].getY();
}
}

//斜等测轴测投影图
void CPoint3D::cavalier_projection(CPoint3D points_3d[], CPoint points[], int point_number)
{
const double PI = 3.1415926535;
MatrixTransformation3D matrix_transformation_3d(points_3d, point_number);
matrix_transformation_3d.oblique_projection(PI / 4, PI / 4); //alpha = PI / 4, beta = PI / 4
matrix_transformation_3d.matrixTo3DPoint(points_3d, point_number);
CPoint3DToCPoint(points_3d, points, point_number);
}

//斜二测轴测投影图
void CPoint3D::cabinet_projection(CPoint3D points_3d[], CPoint points[], int point_number)
{
const double PI = 3.1415926535;
MatrixTransformation3D matrix_transformation_3d(points_3d, point_number);
matrix_transformation_3d.oblique_projection(63.4 * PI / 180, PI / 4); //alpha = 63.4 * PI / 180, beta = PI / 4
matrix_transformation_3d.matrixTo3DPoint(points_3d, point_number);
CPoint3DToCPoint(points_3d, points, point_number);
}

MatrixTransformation3D.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
34
35
#pragma once

#include "CPoint3D.h"

class MatrixTransformation3D
{
public:
MatrixTransformation3D();
~MatrixTransformation3D();

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

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

public:
MatrixTransformation3D(CPoint3D 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();
int round(double value);
public:
CPoint3D* MatrixTransformation3D::matrixTo3DPoint(CPoint3D points[], int point_number);//矩阵转为点数组
void MatrixTransformation3D::oblique_projection(double alpha, double beta);//斜投影
};

MatrixTransformation3D.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
#include "stdafx.h"
#include "MatrixTransformation3D.h"



MatrixTransformation3D::MatrixTransformation3D()
{
row = 0;
column = 0;
pointMatrix = NULL;
}
MatrixTransformation3D::MatrixTransformation3D(CPoint3D points[], int pointNumber)
{
row = pointNumber;
column = 4;
pointMatrix = new double[row * column];

for (int i = 1; i <= row; i++)
{
setMatrixElement(i, 1, points[i - 1].getX());
setMatrixElement(i, 2, points[i - 1].getY());
setMatrixElement(i, 3, points[i - 1].getZ());
setMatrixElement(i, 4, 1);
}
}

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

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

bool MatrixTransformation3D::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 MatrixTransformation3D::getMatrixElement(int row, int column)
{
return getMatrixElement(row, column, pointMatrix);
}

double MatrixTransformation3D::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 MatrixTransformation3D::setTransforMatrixElement(int row, int column, double value)
{
if (row <= this->row && row > 0 && column <= this->column && column > 0)
{
transforMatrix[row - 1][column - 1] = value;
return true;
}

return false;
}

void MatrixTransformation3D::matrixMultiplication()
{
double* result = new double[row * column];
double tempResult;
for (int m = 0; m < row; m++)
{
for (int s = 0; s < column; s++)
{
tempResult = 0.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;
}

int MatrixTransformation3D::round(double value)
{
return (int)(value + 0.5);
}

CPoint3D* MatrixTransformation3D::matrixTo3DPoint(CPoint3D points[], int point_number)
{
for (int i = 1; i <= point_number; i++)
{
points[i - 1].setX(round(getMatrixElement(i, 1)));
points[i - 1].setY(round(getMatrixElement(i, 2)));
points[i - 1].setZ(round(getMatrixElement(i, 3)));
}
return points;
}

//斜投影
void MatrixTransformation3D::oblique_projection(double alpha, double beta)
{
setTransforMatrixElement(1, 1, 1);
setTransforMatrixElement(1, 2, 0);
setTransforMatrixElement(1, 3, 0);
setTransforMatrixElement(1, 4, 0);
setTransforMatrixElement(2, 1, 0);
setTransforMatrixElement(2, 2, 1);
setTransforMatrixElement(2, 3, 0);
setTransforMatrixElement(2, 4, 0);
setTransforMatrixElement(3, 1, -cos(beta) / tan(alpha));
setTransforMatrixElement(3, 2, -sin(beta) / tan(alpha));
setTransforMatrixElement(3, 3, 0);
setTransforMatrixElement(3, 4, 0);
setTransforMatrixElement(4, 1, 0);
setTransforMatrixElement(4, 2, 0);
setTransforMatrixElement(4, 3, 0);
setTransforMatrixElement(4, 4, 1);

matrixMultiplication();
}
扫描二维码,拯救贫困山区大学生!
-------------本文结束感谢您的阅读-------------