图形学实验

这个学期图形学课上的一些作业和实验,都做在了一个Qt的项目里了。准备清理电脑时看到构建文件,想想删之前还是先找个地方把代码记录一下,虽然没什么含金量,但怎么说也是自己一点点写的。

图形学这门课其实是门好课,我也挺喜欢的,但是学校实在是太水了,从教材到老师到课程内容都非常一般,一个学期下来几乎没学到东西。最后期末考我也是想不明白为什么要考默写,考简答,我是真的流汗黄豆了。

head files

Bezier.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
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
#ifndef BEZIER_H
#define BEZIER_H

#include "QList"
#include "QPoint"
#include "QPainter"
#include "QPainterPath"
template<typename Point>
class Bezier
{
private:
double precision = 0.01; //你可以自己设置精度,确保所画直线的细腻程度
QList<Point> * pointList;
private:
void AllBernstein(int n, double u, double *B);
Point PointOnBezierCurve(double u);
public:
Bezier();
~Bezier();
void setPrecision(double precision);
void appendPoint(Point point);
QPainterPath getPainterPath();
double getPrecision();
};
template<typename Point>

Bezier<Point>::Bezier()
{
pointList = new QList<Point>;
}

template<typename Point>
Bezier<Point>::~Bezier()
{
delete pointList;
}


template<typename Point>
void Bezier<Point>::appendPoint(Point point)
{
pointList->append(point);
}
template<typename Point>

QPainterPath Bezier<Point>::getPainterPath()
{
QPainterPath path;
path.moveTo(pointList->at(0));

for (double t = 0; t<1; t += precision)
{
Point pTemp = PointOnBezierCurve(t);
path.lineTo(pTemp);
}
return path;
}

template<typename Point>
void Bezier<Point>::setPrecision(double precision)
{
if (precision<1)
this->precision = precision;
}

template<typename Point>

double Bezier<Point>::getPrecision()
{
return this->precision;
}
template<typename Point>
void Bezier<Point>::AllBernstein(int n, double u, double *B)
{
B[0] = 1.0;
double u1 = 1.0 - u;
for (int j = 1; j <= n; j++)
{
double saved = 0.0;
for (int k = 0; k<j; k++)
{
double temp = B[k];
B[k] = saved + u1*temp;
saved = u*temp;
}
B[j] = saved;
}
}

template<typename Point>
Point Bezier<Point>::PointOnBezierCurve(double u)
{
int n = pointList->length();
double *coefficient = new double[n]; //系数数组
memset(coefficient, 0, sizeof(coefficient));
AllBernstein(n - 1, u, coefficient);//计算系数
Point tempPoint(0.0, 0.0);
for (int i = 0; i<pointList->length(); i++)
{
Point temp = pointList->at(i);
tempPoint = tempPoint + temp*coefficient[i];
}
return tempPoint;
}

#endif // BEZIER_H

BSpline.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
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
#ifndef BSPLINE_H
#define BSPLINE_H

#include "QList"
#include "QPoint"
#include "QPainter"
#include "QPainterPath"
template<typename Point>
class BSpline
{
private:
double precision = 0.001; //你可以自己设置精度,确保所画直线的细腻程度
QList<Point> * pointList;
private:
void AllBernstein(int n, double u, double *B);
Point PointOnBYTCurve(double u);
double getC(int n1, int j);
public:
BSpline();
~BSpline();
void setPrecision(double precision);
void appendPoint(Point point);
QPainterPath getPainterPath();
double getPrecision();
};
template<typename Point>

BSpline<Point>::BSpline()
{
pointList = new QList<Point>;
}

template<typename Point>
BSpline<Point>::~BSpline()
{
delete pointList;
}


template<typename Point>
void BSpline<Point>::appendPoint(Point point)
{
pointList->append(point);
}
template<typename Point>

QPainterPath BSpline<Point>::getPainterPath()
{
QPainterPath path;

for (double t = 0; t<1; t += precision)
{
Point pTemp = PointOnBYTCurve(t);
if (t == 0.0) path.moveTo(pTemp);
path.lineTo(pTemp);
}
return path;
}

template<typename Point>
void BSpline<Point>::setPrecision(double precision)
{
if (precision<1)
this->precision = precision;
}

template<typename Point>

double BSpline<Point>::getPrecision()
{
return this->precision;
}
template<typename Point>
void BSpline<Point>::AllBernstein(int n, double u, double *B)
{
double xishu = 1;
for (int i = 2; i <= n; i++)
xishu *= i;
for (int k = 0; k <= n; k++)
{
B[k] = 0.0;
for (int j = 0; j <= n - k; j++)
{
double temp = 0.0;
temp = j % 2 == 0 ? 1 : -1;
temp *= getC(n + 1, j);
temp *= pow((u + n - k - j), n);
B[k] += temp;
}
B[k] /= xishu;
}
}
template<typename Point>
double BSpline<Point>::getC(int n1, int j) {
double res = 1;
for (int t = 1, n2 = n1; t <= j; t++) {
res *= n2;
n2--;
}
for (int t = 1; t <= j; t++)
res /= t;
return res;
}
template<typename Point>
Point BSpline<Point>::PointOnBYTCurve(double u)
{
int n = pointList->length();
double *coefficient = new double[n]; //系数数组
memset(coefficient, 0, sizeof(coefficient));
AllBernstein(n - 1, u, coefficient);//计算系数
Point tempPoint(0.0, 0.0);
for (int i = 0; i<pointList->length(); i++)
{
Point temp = pointList->at(i);
tempPoint = tempPoint + temp*coefficient[i];
}
return tempPoint;
}

#endif // BSPLINE_H

matrix.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
36
37
38
#ifndef MATRIX_H
#define MATRIX_H

#include <iostream>
#include <cmath>
using namespace std;

class matrix
{

public:
matrix(int r = 2, int c = 2);
matrix(matrix &m);
~matrix();
void GetValue(void);
void SetTranslationThree(void);
void SetRotationThree(void);
void SetZoomThree(void);
void SetoneThree(int a, int b);
int GetoneThreea();
int GetoneThreeb();
matrix operator =(matrix &m);
matrix operator +(matrix &m);
matrix operator -(matrix &m);
matrix operator *(matrix &m);
double operator ()(int x, int y);
matrix rev(void);
friend ostream & operator <<(ostream & out, matrix &m);

private:
int row;
int col;
double **p;

};

#endif // MATRIX_H

mainwindow.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
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
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMessageBox>
#include <QPainter>
#include "matrix.h"
#include "Bezier.h"
#include "BSpline.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

struct Rectangle
{
int xmin, xmax;
int ymin, ymax;
};

struct GPoint
{
int x, y;
};

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();

void paintEvent(QPaintEvent *) override;

int status = 0;
QPoint triPoint[3];
QPoint mPoint[9];
QPointF pTwo[3], pThree[4];

void DDA(QImage *image, int x1, int y1, int x2, int y2, QRgb value);
void Hexagon(QImage *image, int x, int y, int wide, QRgb value);
void Bresenham(QImage *image, int x1, int y1, int x2, int y2, QRgb value);
void CirclePlot(QImage *image, int xc, int yc, int x, int y, QRgb value);
void MidCircle(QImage *image, int xc, int yc, int r, QRgb value);
void Triangle(QImage *image, QPoint apoint, QPoint bpoint, QPoint cpoint, QRgb value);

void Translation(QImage *image, QPoint apoint, QPoint bpoint, QPoint cpoint, QRgb value);
void Rotation(QImage *image, QPoint apoint, QPoint bpoint, QPoint cpoint, QRgb value);
void Zoom(QImage *image, QPoint apoint, QPoint bpoint, QPoint cpoint, QRgb value);

double FindMax(double *elem, int N);
double FindMin(double *elem, int N);
void SuitableX(double *x, double *y, int N, double now_y, double *suitable_x, int &n);
void Functionline(double x1, double y1, double x2, double y2, double &k, double &b);
double SolveX(double k, double b, double now_y);
void SortMintoMax(double suitable_x[], int n);
void ScanLineFill(QImage *image, QPoint *point, QRgb value);

int Encode(int x, int y, Rectangle *rect);
void CohenSutherlandClip(QImage *image, Rectangle *rect, int x1, int y1, int x2, int y2, QRgb value);

void BezierFreeLine();
void BSplineFreeLine();

public slots:
void DDALine();
void BresenhamLine();
void HexagonDraw();
void CircleDraw();
void TriangleDraw();
void TranslationMove();
void RotationMove();
void ZoomMove();
void ScanLineFillDraw();
void CohenSutherlandClipDraw();
void BezierDraw();
void BSplineDraw();

private:
Ui::MainWindow *ui;
QPainter *painter;
};
#endif // MAINWINDOW_H

source files

matrix.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#include "matrix.h"

matrix::matrix(int r, int c)
{
int i;
row = r;
col = c;
p = new double*[row];
for (i = 0; i < row; i++)
*(p + i) = new double[col];
}


matrix::matrix(matrix &m)
{
int i, j;
row = m.row;
col = m.col;
p = new double*[row];
for (i = 0; i < row; i++)
*(p + i) = new double[col];
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
*(*(p + i) + j) = *(*(m.p + i) + j);
}


matrix::~matrix()
{
int i;
for (i = 0; i < row; i++)
delete[] * (p + i);
delete[]p;
}


void matrix::GetValue(void)
{
int i, j;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
cin >> *(*(p + i) + j);
}
void matrix::SetTranslationThree(void)
{
p[0][0] = 1;
p[0][1] = 0;
p[0][2] = 0;

p[1][0] = 0;
p[1][1] = 1;
p[1][2] = 0;

p[2][0] = 50;
p[2][1] = 50;
p[2][2] = 1;
}

void matrix::SetRotationThree(void)
{
p[0][0] = sqrt(3) / 2;
p[0][1] = 1 / 2;
p[0][2] = 0;

p[1][0] = -1 / 2;
p[1][1] = sqrt(3) / 2;
p[1][2] = 0;

p[2][0] = 0;
p[2][1] = 0;
p[2][2] = 1;
}

void matrix::SetZoomThree(void)
{
p[0][0] = 0.5;
p[0][1] = 0;
p[0][2] = 0;

p[1][0] = 0;
p[1][1] = 0.5;
p[1][2] = 0;

p[2][0] = 0;
p[2][1] = 0;
p[2][2] = 1;
}

void matrix::SetoneThree(int a, int b)
{
p[0][0] = a;
p[0][1] = b;
p[0][2] = 1;
}
int matrix::GetoneThreea()
{
return p[0][0];
}
int matrix::GetoneThreeb()
{
return p[0][1];
}
matrix matrix::operator = (matrix &m)
{
int i, j;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
*(*(p + i) + j) = *(*(m.p + i) + j);
return (*this);
}


matrix matrix:: operator +(matrix &m)
{
int i, j;
matrix a(row, col);
if (row != m.row || col != m.col)
throw 0;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
*(*(a.p + i) + j) = *(*(p + i) + j) + *(*(m.p + i) + j);
return(a);
}


matrix matrix::operator -(matrix &m)
{
int i, j;
matrix a(row, col);
if (row != m.row || col != m.col)
throw 0;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
*(*(a.p + i) + j) = *(*(p + i) + j) - *(*(m.p + i) + j);
return(a);
}


matrix matrix::operator *(matrix &m)
{
if (col != m.row)
throw 0;
int i, j, k;
double sum;
matrix a(row, m.col);
for (i = 0; i < row; i++)
for (j = 0; j < m.col; j++)
{
for (k = 0, sum = 0; k < col; k++)
sum = sum + *(*(p + i) + k) * *(*(m.p + k) + j);
*(*(a.p + i) + j) = sum;
}
return a;
}


double matrix::operator ()(int x, int y)
{
if (x > row || y > col)
throw 0.0;
return(*(*(p + x - 1) + y - 1));
}


matrix matrix::rev(void)
{
int i, j;
matrix a(col, row);
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
*(*(a.p + j) + i) = *(*(p + i) + j);
return(a);
}


ostream & operator <<(ostream & out, matrix &m)
{
int i, j;
for (i = 0; i < m.row; i++)
{
for (j = 0; j < m.col; j++)
out << *(*(m.p + i) + j) << " ";
out << endl;
}
return(out);
}

mainwindow.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);

connect(ui->actionDDA, SIGNAL(triggered()), this, SLOT(DDALine()));
connect(ui->actionBresenham, SIGNAL(triggered()), this, SLOT(BresenhamLine()));
connect(ui->actionHexagon, SIGNAL(triggered()), this, SLOT(HexagonDraw()));
connect(ui->actionCircle, SIGNAL(triggered()), this, SLOT(CircleDraw()));
connect(ui->actionTriangle, SIGNAL(triggered()), this, SLOT(TriangleDraw()));
connect(ui->actionTranslation, SIGNAL(triggered()), this, SLOT(TranslationMove()));
connect(ui->actionRotation, SIGNAL(triggered()), this, SLOT(RotationMove()));
connect(ui->actionZoom, SIGNAL(triggered()), this, SLOT(ZoomMove()));
connect(ui->actionScanLineFill, SIGNAL(triggered()), this, SLOT(ScanLineFillDraw()));
connect(ui->actionCohenSutherlandClip, SIGNAL(triggered()), this, SLOT(CohenSutherlandClipDraw()));
connect(ui->actionBezier, SIGNAL(triggered()), this, SLOT(BezierDraw()));
connect(ui->actionBSpline, SIGNAL(triggered()), this, SLOT(BSplineDraw()));

triPoint[0].setX(250); triPoint[0].setY(250);
triPoint[1].setX(150); triPoint[1].setY(450);
triPoint[2].setX(350); triPoint[2].setY(450);

mPoint[0].setX(200); mPoint[0].setY(200);
mPoint[1].setX(100); mPoint[1].setY(300);
mPoint[2].setX(150); mPoint[2].setY(400);
mPoint[3].setX(170); mPoint[3].setY(150);
mPoint[4].setX(400); mPoint[4].setY(350);
mPoint[5].setX(350); mPoint[5].setY(300);
mPoint[6].setX(300); mPoint[6].setY(250);
mPoint[7].setX(250); mPoint[7].setY(100);
mPoint[8].setX(270); mPoint[8].setY(270);

pTwo[0] = QPointF(50, 300);
pTwo[1] = QPointF(350, 50);
pTwo[2] = QPointF(500, 350);

pThree[0] = QPointF(50, 300);
pThree[1] = QPointF(200, 100);
pThree[2] = QPointF(350, 100);
pThree[3] = QPointF(500, 350);

}


void MainWindow::DDALine()
{
status = 1;
repaint();
}

void MainWindow::BresenhamLine()
{
status = 2;
repaint();
}

void MainWindow::HexagonDraw()
{
status = 3;
repaint();
}

void MainWindow::CircleDraw()
{
status = 4;
repaint();
}

void MainWindow::TriangleDraw()
{
status = 5;
repaint();
}

void MainWindow::TranslationMove()
{
status = 6;
repaint();
}

void MainWindow::RotationMove()
{
status = 7;
repaint();
}

void MainWindow::ZoomMove()
{
status = 8;
repaint();
}

void MainWindow::ScanLineFillDraw()
{
status = 9;
repaint();
}

void MainWindow::CohenSutherlandClipDraw()
{
status = 10;
repaint();
}

void MainWindow::BezierDraw()
{
status = 11;
repaint();
}

void MainWindow::BSplineDraw()
{
status = 12;
repaint();
}

void MainWindow::paintEvent(QPaintEvent *)
{
// QPainter painter(this);
// painter.setPen(QPen(Qt::blue, 4));
// painter.drawLine(20, 20, 220, 220);
// painter.drawLine(20, 220, 220, 20);
// painter.drawEllipse(20, 20, 200, 200);
// painter.drawRect(20, 20, 200, 200);

Rectangle rect;
rect.xmin = 200; rect.ymin = 200;
rect.xmax = 400; rect.ymax = 400;

QImage *image = new QImage(800, 600, QImage::Format_RGB32);
painter = new QPainter(this);

// painter->begin(this);
//image->fill(qRgba(255, 255, 255, 0));
switch(status)
{
case 0: painter->drawImage(0, 0, *image); break;
case 1: DDA(image, 120, 120, 240, 240, qRgb(255, 0, 0)); painter->drawImage(0, 0, *image); break;
case 2: Bresenham(image, 300, 300, 500, 150, qRgb(0, 0, 255)); painter->drawImage(0, 0, *image); break;
case 3: Hexagon(image, 300, 300, 100, qRgb(0, 255, 0)); painter->drawImage(0, 0, *image); break;
case 4: MidCircle(image, 250, 250, 100, qRgb(123, 123, 123)); painter->drawImage(0, 0, *image); break;
case 5: Triangle(image, QPoint(250, 250), QPoint(150, 450), QPoint(350, 450), qRgb(114, 51, 4)); painter->drawImage(0, 0, *image); break;
case 6: Translation(image, triPoint[0], triPoint[1], triPoint[2], qRgb(114, 51, 4)); painter->drawImage(0, 0, *image); break;
case 7: Rotation(image, triPoint[0], triPoint[1], triPoint[2], qRgb(114, 51, 4)); painter->drawImage(0, 0, *image); break;
case 8: Zoom(image, triPoint[0], triPoint[1], triPoint[2], qRgb(114, 51, 4)); painter->drawImage(0, 0, *image); break;
case 9: ScanLineFill(image, mPoint, qRgb(1, 12, 123)); painter->drawImage(0, 0, *image); break;
case 10: CohenSutherlandClip(image, &rect, 50, 50, 480, 450, qRgb(123, 12, 1)); painter->drawImage(0, 0, *image); break;
case 11: BezierFreeLine(); break;
case 12: BSplineFreeLine(); break;

default: break;
}

// painter->drawImage(0, 0, *image);
// delete image;
painter->end();
}

void MainWindow::DDA(QImage *image, int x1, int y1, int x2, int y2, QRgb value)
{
int x;
float dx, dy, y, k;
dx = x2 - x1;
dy = y2 - y1;
k = dy / dx; //计算k
y = y1;
for(x = x1; x < x2; x++) //x的步长为1
{
image->setPixel(x, (int)(y + 0.5), value);
y = y + k; //y的步长为k
}
}

void MainWindow::Bresenham(QImage *image, int x1, int y1, int x2, int y2, QRgb value)
{
int x = x1, y = y1;
int dx = abs(x2 - x1), dy = abs(y2 - y1);

int s1;
if(x2 > x1) //判断直线的方向
s1 = 1;
else
s1 = -1;
int s2;
if(y2 > y1)
s2 = 1;
else
s2 = -1;

int interchange;
if(dy > dx)
{
int temp = dx;
dx = dy;
dy = temp;
interchange = 1;
}
else
interchange = 0;

int p = 2 * dy - dx;
for(int i = 1; i <= dx; i++)
{
image->setPixel(x, y, value);
if(p >= 0)
{
if(interchange == 0)
y = y + s2;
else
x = x + s1;
p = p - 2 * dx;
}
if(interchange == 0)
x = x + s1;
else
y = y + s2;
p = p + 2 * dy;
}
}


void MainWindow::Hexagon(QImage *image, int X, int Y, int length, QRgb value)
{
double len = (double)length, x = (double)X, y = (double)Y; //预处理边长
Bresenham(image, x - len * sqrt(3) / 2, y - length / 2, x - len * sqrt(3) / 2, y + length / 2, value);
Bresenham(image, x - len * sqrt(3) / 2, y + length / 2, x, y + length, value);
Bresenham(image, x, y + length, x + len * sqrt(3) / 2, y + length / 2, value);
Bresenham(image, x + len * sqrt(3) / 2, y + length / 2, x + len * sqrt(3) / 2, y - length / 2, value);
Bresenham(image, x + len * sqrt(3) / 2, y - length / 2, x, y - length, value);
Bresenham(image, x, y - length, x - len * sqrt(3) / 2, y - length / 2, value);
}

void MainWindow::CirclePlot(QImage *image, int xc, int yc, int x, int y, QRgb value)
{
image->setPixel(xc + x, yc + y, value);
image->setPixel(xc - x, yc + y, value);
image->setPixel(xc + x, yc - y, value);
image->setPixel(xc - x, yc - y, value);
image->setPixel(xc + y, yc + x, value);
image->setPixel(xc - y, yc + x, value);
image->setPixel(xc + y, yc - x, value);
image->setPixel(xc - y, yc - x, value);

}

void MainWindow::MidCircle(QImage *image, int xc, int yc, int r, QRgb value)
{
int x = 0, y = r, e = 1 - r;
CirclePlot(image, xc, yc, x, y, value);
while (x <= y)
{
if (e < 0)
e += 2 * x + 3;
else
{
e += 2 * (x - y) + 5;
y--;
}
x++;
CirclePlot(image, xc, yc, x, y, value); //调用CirclePlot
}
}

void MainWindow::Triangle(QImage *image, QPoint apoint, QPoint bpoint, QPoint cpoint, QRgb value)
{
Bresenham(image, apoint.x(), apoint.y(), bpoint.x(), bpoint.y(), value);
Bresenham(image, cpoint.x(), cpoint.y(), bpoint.x(), bpoint.y(), value);
Bresenham(image, apoint.x(), apoint.y(), cpoint.x(), cpoint.y(), value);
}


void MainWindow::Translation(QImage *image, QPoint apoint, QPoint bpoint, QPoint cpoint, QRgb value)
{
matrix ThreeThreeMatrix(3, 3), ap(1, 3), bp(1, 3), cp(1, 3);
ThreeThreeMatrix.SetTranslationThree(); //设置平移矩阵
ap.SetoneThree(apoint.x(), apoint.y());
bp.SetoneThree(bpoint.x(), bpoint.y());
cp.SetoneThree(cpoint.x(), cpoint.y());
QPoint A((ap*ThreeThreeMatrix).GetoneThreea(), (ap*ThreeThreeMatrix).GetoneThreeb());
QPoint B((bp*ThreeThreeMatrix).GetoneThreea(), (bp*ThreeThreeMatrix).GetoneThreeb());
QPoint C((cp*ThreeThreeMatrix).GetoneThreea(), (cp*ThreeThreeMatrix).GetoneThreeb());
Bresenham(image, A.x(), A.y(), B.x(), B.y(), value); //重新画线
Bresenham(image, B.x(), B.y(), C.x(), C.y(), value);
Bresenham(image, C.x(), C.y(), A.x(), A.y(), value);
}

void MainWindow::Rotation(QImage *image, QPoint apoint, QPoint bpoint, QPoint cpoint, QRgb value)
{
matrix ThreeThreeMatrix(3, 3), ap(1, 3), bp(1, 3), cp(1, 3);
ThreeThreeMatrix.SetRotationThree(); //设置旋转矩阵
ap.SetoneThree(apoint.x(), apoint.y());
bp.SetoneThree(bpoint.x(), bpoint.y());
cp.SetoneThree(cpoint.x(), cpoint.y());
QPoint A((ap*ThreeThreeMatrix).GetoneThreea(), (ap*ThreeThreeMatrix).GetoneThreeb());
QPoint B((bp*ThreeThreeMatrix).GetoneThreea(), (bp*ThreeThreeMatrix).GetoneThreeb());
QPoint C((cp*ThreeThreeMatrix).GetoneThreea(), (cp*ThreeThreeMatrix).GetoneThreeb());
Bresenham(image, A.x(), A.y(), B.x(), B.y(), value);
Bresenham(image, B.x(), B.y(), C.x(), C.y(), value);
Bresenham(image, C.x(), C.y(), A.x(), A.y(), value);
}

void MainWindow::Zoom(QImage *image, QPoint apoint, QPoint bpoint, QPoint cpoint, QRgb value)
{
matrix ThreeThreeMatrix(3, 3), ap(1, 3), bp(1, 3), cp(1, 3);
ThreeThreeMatrix.SetZoomThree(); //设置缩放矩阵
ap.SetoneThree(apoint.x(), apoint.y());
bp.SetoneThree(bpoint.x(), bpoint.y());
cp.SetoneThree(cpoint.x(), cpoint.y());
QPoint A((ap*ThreeThreeMatrix).GetoneThreea(), (ap*ThreeThreeMatrix).GetoneThreeb());
QPoint B((bp*ThreeThreeMatrix).GetoneThreea(), (bp*ThreeThreeMatrix).GetoneThreeb());
QPoint C((cp*ThreeThreeMatrix).GetoneThreea(), (cp*ThreeThreeMatrix).GetoneThreeb());
Bresenham(image, A.x(), A.y(), B.x(), B.y(), value);
Bresenham(image, B.x(), B.y(), C.x(), C.y(), value);
Bresenham(image, C.x(), C.y(), A.x(), A.y(), value);
}


double MainWindow::FindMax(double *elem, int N) //找最大值
{
double MAX = elem[0];
for(int i = 0; i < N; i++)
if(elem[i] > MAX)
MAX = elem[i];
return MAX;
}

double MainWindow::FindMin(double *elem, int N) //找最小值
{
double MIN = elem[0];
for(int i = 0; i < N; i++)
if(elem[i] < MIN)
MIN = elem[i];
return MIN;
}

void MainWindow::Functionline(double x1, double y1, double x2, double y2, double &k, double &b) //计算直线的k b
{
if(x2 - x1 == 0)
{
k = -9999;
b = x1;
return;
}
k = (y2 - y1) / (x2 - x1);
b = y1 - k * x1;
}

double MainWindow::SolveX(double k, double b, double now_y) //给出直线上一点的y值,计算x的值
{
if(k == -9999)
return b;
return (now_y - b) / k;
}

void MainWindow::SuitableX(double *x, double *y, int N, double now_y, double *suitable_x, int &n) //找出所有的x的值
{
n = 0;
int t = 0;
double k, b;
for(int i = 0; i < N; i++)
if(i == N - 1)
{
if((y[i] < now_y && now_y <= y[0]) || (y[0] < now_y && now_y <= y[i]))
{
Functionline(x[0], y[0], x[i], y[i], k, b);
suitable_x[t++] = SolveX(k, b, now_y);
}
}
else
{
if((y[i] < now_y && now_y <= y[i + 1]) || (y[i + 1] < now_y && now_y <= y[i]))
{
Functionline(x[i], y[i], x[i + 1], y[i + 1], k, b);
suitable_x[t++] = SolveX(k, b, now_y);
}
}
n = t;
}

void MainWindow::SortMintoMax(double *suitable_x, int n) //排序
{
for(int i = 0; i < n - 1; i++)
for(int j = i + 1; j < n; j++)
if(suitable_x[i] > suitable_x[j])
{
double temp = suitable_x[i];
suitable_x[i] = suitable_x[j];
suitable_x[j] = temp;
}
}

void MainWindow::ScanLineFill(QImage *image, QPoint point[], QRgb value) //图形填充
{
double x[50], y[50];
for(int i = 0; i < 9; i++)
{
x[i] = point[i].x();
y[i] = point[i].y();
}
int N = 9;
int n = 0;
double suitable_x[10];
double min_y = FindMin(y, N), max_y = FindMax(y, N);
for(int now_y = min_y; now_y <= max_y; now_y++)
{
SuitableX(x, y, N, now_y, suitable_x, n);
SortMintoMax(suitable_x, n);
for(int i = 0; i < n; i += 2)
for(int now_x = suitable_x[i]; now_x < suitable_x[i + 1]; now_x++)
image->setPixel(now_x, now_y, value);
}
}


int MainWindow::Encode(int x, int y, Rectangle *rect) //计算code
{
int code = 0x0;
if(x < rect->xmin)
code = code | 0x1;
if(x > rect->xmax)
code = code | 0x2;
if(y < rect->ymin)
code = code | 0x4;
if(y > rect->ymax)
code = code | 0x8;
return code;
}

void MainWindow::CohenSutherlandClip(QImage *image, Rectangle *rect, int x1, int y1, int x2, int y2, QRgb value) //图形裁剪
{
int code1 = Encode(x1, y1, rect);
int code2 = Encode(x2, y2, rect);
GPoint p1, p2;
p1.x = x1;
p1.y = y1;
p2.x = x2;
p2.y = y2;
while (code1 != 0 || code2 != 0)
{
if ((code1 & code2) != 0)
return;
if ((code1 & 8) != 0)
{
p1.x -= (p1.y - rect->ymax) * (p1.x - p2.y) / (p1.y - p2.y);
p1.y = rect->ymax;
code1 = Encode(p1.x, p1.y, rect);
}
else if ((code2 & 8) != 0)
{
p2.x -= (p2.y - rect->ymax) * (p2.x - p1.y) / (p2.y - p1.y);
p2.y = rect->ymax;
code2 = Encode(p2.x, p2.y, rect);
}
else if ((code1 & 4) != 0)
{
p1.x -= (p1.y - rect->ymin) * (p1.x - p2.x) / (p1.y - p2.y);
p1.y = rect->ymin;
code1 = Encode(p1.x, p1.y, rect);
}
else if ((code2 & 4) != 0)
{
p2.x -= (p2.y - rect->ymin) * (p2.x - p1.x) / (p2.y - p1.y);
p2.y = rect->ymin;
code2 = Encode(p2.x, p2.y, rect);
}
else if ((code1 & 2) != 0)
{
p1.y -= (p1.x - rect->xmax) * (p1.y - p2.y) / (p1.x - p2.x);
p1.x = rect->xmax;
code1 = Encode(p1.x, p1.y, rect);
}
else if ((code2 & 2) != 0)
{
p2.y -= (p2.x - rect->xmax) * (p2.y - p1.y) / (p2.x - p1.x);
p2.x = rect->xmax;
code2 = Encode(p2.x, p2.y, rect);
}
else if ((code1 & 1) != 0)
{
p1.y -= (p1.x - rect->xmin) * (p1.y - p2.y) / (p1.x - p2.x);
p1.x = rect->xmin;
code1 = Encode(p1.x, p1.y, rect);
}
else if ((code2 & 1) != 0)
{
p2.y -= (p2.x - rect->xmin) * (p2.y - p1.y) / (p2.x - p1.x);
p2.x = rect->xmin;
code2 = Encode(p2.x, p2.y, rect);
}
}
Bresenham(image, p1.x, p1.y, p2.x, p2.y,value);
Bresenham(image, rect->xmin, rect->ymin, rect->xmin, rect->ymax,value);
Bresenham(image, rect->xmax, rect->ymin, rect->xmax, rect->ymax, value);
Bresenham(image, rect->xmin, rect->ymin, rect->xmax, rect->ymin, value);
Bresenham(image, rect->xmin, rect->ymax, rect->xmax, rect->ymax, value);
}



void MainWindow::BezierFreeLine()
{
Bezier<QPointF> *bezier;
QPainterPath path;
bezier = new Bezier<QPointF>();
painter->setPen(Qt::red);
// painter->drawLine(pTwo[0], pTwo[1]);
// painter->drawLine(pTwo[1], pTwo[2]);
painter->drawLine(pThree[0], pThree[1]);
painter->drawLine(pThree[1], pThree[2]);
painter->drawLine(pThree[2], pThree[3]);
// bezier->appendPoint(pTwo[0]);
// bezier->appendPoint(pTwo[1]);
// bezier->appendPoint(pTwo[2]);
bezier->appendPoint(pThree[0]);
bezier->appendPoint(pThree[1]);
bezier->appendPoint(pThree[2]);
bezier->appendPoint(pThree[3]);
path = bezier->getPainterPath();
painter->setPen(Qt::blue);
painter->drawPath(path);
delete bezier;
}

void MainWindow::BSplineFreeLine()
{
BSpline<QPointF> *bspline;
QPainterPath path;
bspline = new BSpline<QPointF>();
painter->setPen(qRgb(215, 42, 88));
// painter->drawLine(pTwo[0], pTwo[1]);
// painter->drawLine(pTwo[1], pTwo[2]);
painter->drawLine(pThree[0], pThree[1]);
painter->drawLine(pThree[1], pThree[2]);
painter->drawLine(pThree[2], pThree[3]);
// bspline->appendPoint(pTwo[0]);
// bspline->appendPoint(pTwo[1]);
// bspline->appendPoint(pTwo[2]);
bspline->appendPoint(pThree[0]);
bspline->appendPoint(pThree[1]);
bspline->appendPoint(pThree[2]);
bspline->appendPoint(pThree[3]);
path = bspline->getPainterPath();
painter->setPen(qRgb(98, 129, 194));
painter->drawPath(path);
delete bspline;
}


MainWindow::~MainWindow()
{
delete ui;
}

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

others

mainwindow.ui

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
137
138
139
140
141
142
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>800</width>
<height>600</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>800</width>
<height>600</height>
</size>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>24</height>
</rect>
</property>
<widget class="QMenu" name="menutest">
<property name="title">
<string>NMSL</string>
</property>
<addaction name="actionDDA"/>
<addaction name="actionBresenham"/>
<addaction name="separator"/>
<addaction name="actionHexagon"/>
<addaction name="actionCircle"/>
<addaction name="actionTriangle"/>
<addaction name="separator"/>
<addaction name="actionTranslation"/>
<addaction name="actionRotation"/>
<addaction name="actionZoom"/>
<addaction name="separator"/>
<addaction name="actionScanLineFill"/>
<addaction name="actionCohenSutherlandClip"/>
<addaction name="separator"/>
<addaction name="actionBezier"/>
<addaction name="actionBSpline"/>
</widget>
<addaction name="menutest"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actiontest">
<property name="text">
<string>test</string>
</property>
</action>
<action name="actiona">
<property name="text">
<string>a</string>
</property>
</action>
<action name="actionDDA">
<property name="text">
<string>DDA</string>
</property>
</action>
<action name="actionHexagon">
<property name="text">
<string>Hexagon</string>
</property>
</action>
<action name="actionBresenham">
<property name="text">
<string>Bresenham</string>
</property>
</action>
<action name="actionCircle">
<property name="text">
<string>Circle</string>
</property>
</action>
<action name="actionTriangle">
<property name="text">
<string>Triangle</string>
</property>
</action>
<action name="actionTranslation">
<property name="text">
<string>Translation</string>
</property>
</action>
<action name="actionRotation">
<property name="text">
<string>Rotation</string>
</property>
</action>
<action name="actionZoom">
<property name="text">
<string>Zoom</string>
</property>
</action>
<action name="actionScanLineFill">
<property name="text">
<string>ScanLineFill</string>
</property>
</action>
<action name="actionCohenSutherlandClip">
<property name="text">
<string>CohenSutherlandClip</string>
</property>
</action>
<action name="actionBezier">
<property name="text">
<string>Bezier</string>
</property>
</action>
<action name="actionBSpline">
<property name="text">
<string>BSpline</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

作者

Jhuoer Yen

发布于

2021-07-09

更新于

2023-09-18

许可协议

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×