计算机图形学笔记一——绘制直线的算法

绘制直线的算法

下一篇->圆形的绘制

数值微分法

数值微分法(digital differential analyzer DDA)使用直线的增量方程来计算直线的下一个迭代点像素的方法。直线的微分方程:
$$
\frac{dy}{dx}=\frac{\Delta y}{\Delta x}=\frac{y_1-y_0}{x_1-x_0}=k
$$
得到迭代公式:
$$
x_{i+1}=x_i+\beta \Delta x
$$
$$
y_{i+1}=y_i +\beta \Delta y
$$
其中$\beta=\frac{1}{max(|\Delta x|,|\Delta y|)}$
也就是说,当斜率的绝对值大于1的时候,取y的步长为1,当斜率的绝对值小于1时,取x的步长为1。然后对非步长点进行近似,得到这样的代码

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
double x, y;
double k; //斜率
k = (static_cast<float>(endy - starty) / static_cast<float>(endx - startx));
x = (double)startx, y = (double)starty;
if (abs(k) < 1.0) {
for (int i = 0; i < abs(endx - startx); i++) {
if (endx > startx) {
x += 1;
y += k;
}
else {
x -= 1;
y -= k;
}
glVertex2d(static_cast<int>(x), static_cast<int>(y + 0.5)); //y四舍五入
}
}
else if (abs(k) > 1.0) {
for (int i = 0; i < abs(endy - starty); i++) {
if (endy > starty) {
y += 1;
x += 1.0 / k;
}
else {
y -= 1;
x -= 1.0 / k;
}
glVertex2d(static_cast<int>(x + 0.5), static_cast<int>(y)); //x四舍五入
}
}

再考虑斜率为0和斜率不存在的情况(垂直x轴和平行x轴),我们可以写出这样的代码,这便是DAA方法的实现。

DAA完整代码

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
void DDA_Line(int startx, int starty, int endx, int endy) {
glBegin(GL_POINTS);
if (startx != endx && starty != endy)
{
double x, y;
double k; //斜率
k = (static_cast<float>(endy - starty) /static_cast<float>(endx - startx));
x = (double)startx, y = (double)starty;
if (abs(k)<1.0) {
for (int i = 0; i < abs(endx - startx); i++) {
if (endx > startx) {
x += 1;
y += k;
}
else {
x -= 1;
y -= k;
}
glVertex2d(static_cast<int>(x), static_cast<int>(y+0.5)); //y四舍五入
}
}
else if (abs(k) > 1.0) {
for (int i = 0; i < abs(endy - starty); i++) {
if (endy > starty) {
y += 1;
x += 1.0/k;
}
else {
y -= 1;
x -= 1.0/k;
}
glVertex2d(static_cast<int>(x + 0.5), static_cast<int>(y)); //x四舍五入
}
}
}
else if (startx == endx) {//垂直画线
if (starty < endy) {
for (int i = starty; i < endy; i++) {
glVertex2d(startx, i);
}
}
else if (starty > endy) {
for (int i = endy; i < starty; i++) {
glVertex2d(startx, i);
}
}
}
else if (starty == endy) {//水平画线
if (startx < endx) {
for (int i = startx; i < endx; i++) {
glVertex2d(i, starty);
}
}
else if (startx > endx) {
for (int i = endx; i < startx; i++) {
glVertex2d(i, starty);
}
}
}
glFlush();
glEnd();
}

中点画线算法

不进行除法运算,减少计算量,使用一种近似的思想进行取样。下面两幅图中说明了这种算法的实施方法:
image
当曲线在一格的中间偏上时,使用上面的点作为采样点,当在中间偏下时,使用下面的一格。如此计算,便能绕靠斜率的除法运算。
实际实现方法:从左边的点开始,每次往右移动一格,计算这个点的中点处y与函数值的差,如果大于零,则y不变;反之y向上(下)移动一格。
那么有两个要求:
一、计算y移动的方向是上还是下
二、开始的点必须在左边

分析一下这个差值的计算:
$$
F(x,y)=ax+by+c=0

a=y_0-y_1

b=x_1-x_0

c=x_0y_1-x_1y_0

d=F(x_i+1,y_i+0.5)
$$
其中d也就是中点和直线的竖直距离,我们可以通过判断d的正负来进行采样。进一步分析
当d>=0时,下一个构造点为F$x_i+2,y_i$,那么

$$
d_1=a(x_i+1+1)+b(y_i+0.5)+c=d+a
$$
同理,当$d<0$时d$_1=F(x_i+2,y_i+1.5)$,即:

$d=a(x_i+2)+b(y_i+1.5)+c=d+a+b$

这样我们就得到了迭代方程,我们可以写出这样的代码:

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
if (startx != endx && starty != endy)
{
bool kFlag = 0; //斜率是否大于1
int sFlag = 1; //斜率的正负
if (startx > endx) { //因为算法是x递增的,所以要保持起点x在终点左边
int tempx = startx, tempy = starty;
startx = endx, starty = endy;
endx = tempx, endy = tempy;
}
if (abs(starty - endy) > abs(startx - endx)) {
kFlag = true;
}
if (starty > endy) { //标记斜率小于零
sFlag = -1;
}
int a, b, TA, TAB, d, x, y;
if (sFlag == -1)
endy = starty + (starty - endy);

a = starty - endy;
b = endx - startx;
TA = 2 * a; //twoA
TAB = 2 * (a + b); //twoAB
d = 2 * a + b;
x = startx, y = starty;
if (!kFlag) {
for (int i = 0; i < (endx - startx); i++) {
if (d >= 0) {
glVertex2i(++x, y);
d += TA;
}
else {
glVertex2i(++x, y += sFlag);
d += TAB;
}
}
}
else if (kFlag) {
if (kFlag == 1) {
TA = 2 * b;
d = 2 * b + a;
}
for (int i = 0; i < abs(endy - starty); i++) {
if (d >= 0) {
glVertex2i(++x, y += sFlag);
d += TAB;
}
else {
glVertex2i(x, y += sFlag);
d += TA;
}
}
}
}

你可以在这里找到所有代码

TMP算法完整代码

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
void TMP_Line(int startx, int starty, int endx, int endy) {
glBegin(GL_POINTS);
if (startx != endx && starty != endy)
{
bool kFlag = 0; //斜率是否大于1
int sFlag = 1; //斜率的正负
if (startx > endx) { //因为算法是x递增的,所以要保持起点x在终点左边
int tempx = startx, tempy = starty;
startx = endx, starty = endy;
endx = tempx, endy = tempy;
}
if (abs(starty - endy) > abs(startx - endx)) {
kFlag = true;
}
if (starty > endy) { //标记斜率小于零
sFlag = -1;
}
int a, b, TA, TAB, d, x, y;
if (sFlag == -1)
endy = starty + (starty - endy);

a = starty - endy;
b = endx - startx;
TA = 2 * a; //twoA
TAB = 2 * (a + b); //twoAB
d = 2 * a + b;
x = startx, y = starty;
if (!kFlag) {
for (int i = 0; i < (endx - startx); i++) {
if (d >= 0) {
glVertex2i(++x, y);
d += TA;
}
else {
glVertex2i(++x , y +=sFlag);
d += TAB;
}
}
}
else if (kFlag) {
if (kFlag == 1) {
TA = 2 * b;
d = 2 * b + a;
}
for (int i = 0; i < abs(endy - starty); i++) {
if (d >= 0) {
glVertex2i(++x , y +=sFlag);
d += TAB;
}
else {
glVertex2i(x, y+=sFlag);
d += TA;
}
}
}
}
else if (startx == endx) {//垂直画线
if (starty < endy) {
for (int i = starty; i < endy; i++) {
glVertex2i(startx, i);
}
}
else if (starty > endy) {
for (int i = endy; i < starty; i++) {
glVertex2i(startx, i);
}
}
}
else if (starty == endy) {//水平画线
if (startx < endx) {
for (int i = startx; i < endx; i++) {
glVertex2i(i, starty);
}
}
else if (startx > endx) {
for (int i = endx; i < startx; i++) {
glVertex2i(i, starty);
}
}
}
glFlush();
glEnd();
}

Bresenham画线算法

这是目前计算机图形学使用的最多的直线生成算法。在计算最佳逼近中使用的全部都是整数运算,可以大幅度的提升计算速度。
与TMP不同的一点就是,TMP是计算中点与直线上的点,而Bresenham是计算上下格子与直线竖直距离的差。也就是下面图像中的d2-d1
image
推导过程如下:
直线方程可以表示为(不管两种特殊情况)

$$
y=kx+b

k=\frac{y_1-y_0}{x_1-x_0}=\frac{dy}{dx},b=y_0-kx_0
$$

当 $ 0<k<1$时直线向正方向前进一个像素,对应的最佳逼近的 $x_{i+1}=x_i+1$, $y_{i+1}=y_i+1$or $y_i$

$$
y=k(x_i+1)+b

d_1=y-y_i

d_2=y_i+1-y
$$

$$
d_1-d_2=2y-2y_i-1=2(k(x_i+1)+b)-2y_i-1
$$

当 $d_1-d_2>0$时

$y_{i+1}=y_i+1$

当 $d_1-d_2<=0$时

$y_{i+1}=y_i$

魔法:当dx>0时,把 $d_10d_2$乘上$dx$,不影响整个式子的正负得到:

$$
p_i=dx(d_1-d_2)
$$

$$
k=\frac{dy}{dx}
$$

所以

$$
p_i=2x_0dy-2y_idx+2dy+(2b-1)dx
$$

当i=0时,得到迭代起点:

$$
p_0=2dy-dx
$$

当 $p_i>0时$

$$
p_{i+1}=pi+2dy-2dx
$$

当 $p_i<=0时$

$$
p_{i+1}=p_i+2dy
$$

推导到此结束,下面是实现,这个实现和TMP十分相似,但是计算量比TMP稍微小一点。

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
if (startx != endx && starty != endy) {
bool kFlag = 0; //斜率是否大于1
int sFlag = 1; //斜率的正负
if (startx > endx) { //因为算法是x递增的,所以要保持起点x在终点左边
int tempx = startx, tempy = starty;
startx = endx, starty = endy;
endx = tempx, endy = tempy;
}
if (abs(starty - endy) > abs(startx - endx)) {
kFlag = true;
}
if (starty > endy) { //标记斜率小于零
sFlag = -1;
}
int x, y;
int dx, dy, p;
if (sFlag == -1)
endy = starty + (starty - endy);
dx = endx - startx;
dy = endy - starty;
x = startx, y = starty;
if (!kFlag) {
p = 2 * dy - dx;
for (int i = 0; i < (endx - startx); i++) {
if (p <= 0) {
glVertex2i(++x, y);
p += 2 * dy;
}
else {
glVertex2i(++x, y += sFlag);
p += 2 * dy - 2 * dx;
}
}
}
else {
p = 2 * dx - dy;
for (int i = 0; i < (endy - starty); i++) {
if (p <= 0) {
glVertex2i(x, y += sFlag);
p += 2 * dx;
}
else {
glVertex2i(++x, y += sFlag);
p += 2 * dx - 2 * dy;
}
}
}
}

同样的,你可以在这里找到完整代码:

BRESENHAM算法完整代码

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
void BRESENHAM_Line(int startx, int starty, int endx, int endy) {
glBegin(GL_POINTS);
if (startx != endx && starty != endy) {
bool kFlag = 0; //斜率是否大于1
int sFlag = 1; //斜率的正负
if (startx > endx) { //因为算法是x递增的,所以要保持起点x在终点左边
int tempx = startx, tempy = starty;
startx = endx, starty = endy;
endx = tempx, endy = tempy;
}
if (abs(starty - endy) > abs(startx - endx)) {
kFlag = true;
}
if (starty > endy) { //标记斜率小于零
sFlag = -1;
}
int x, y;
int dx, dy, p;
if (sFlag == -1)
endy = starty + (starty - endy);
dx = endx - startx;
dy = endy - starty;
x = startx, y = starty;
if (!kFlag) {
p = 2 * dy - dx;
for (int i = 0; i < (endx - startx); i++) {
if (p <= 0) {
glVertex2i(++x, y);
p += 2 * dy;
}
else {
glVertex2i(++x, y += sFlag);
p += 2 * dy - 2 * dx;
}
}
}
else {
p = 2 * dx - dy;
for (int i = 0;i < (endy - starty); i++) {
if (p <= 0) {
glVertex2i(x, y += sFlag);
p += 2 * dx;
}
else {
glVertex2i(++x, y += sFlag);
p += 2 * dx - 2 * dy;
}
}
}
}
else if (startx == endx) {//垂直画线
if (starty < endy) {
for (int i = starty; i < endy; i++) {
glVertex2i(startx, i);
}
}
else if (starty > endy) {
for (int i = endy; i < starty; i++) {
glVertex2i(startx, i);
}
}
}
else if (starty == endy) {//水平画线
if (startx < endx) {
for (int i = startx; i < endx; i++) {
glVertex2i(i, starty);
}
}
else if (startx > endx) {
for (int i = endx; i < startx; i++) {
glVertex2i(i, starty);
}
}
}
glFlush();
glEnd();
}

代码汇总

DrawLine.hpp代码

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
//DrawLine.hpp
#pragma once
#include <cmath>
#include <gl/glut.h>

/*
数值微分算法实现
*/
/// <summary>
/// digitial differential analyzer
/// called DAA
/// </summary>
/// <param name="startx">起始位置x</param>
/// <param name="starty"></param>
/// <param name="endx">终止位置x</param>
/// <param name="endy"></param>
void DDA_Line(int startx, int starty, int endx, int endy) {
glBegin(GL_POINTS);
if (startx != endx && starty != endy)
{
double x, y;
double k; //斜率
k = (static_cast<float>(endy - starty) /static_cast<float>(endx - startx));
x = (double)startx, y = (double)starty;
if (abs(k)<1.0) {
for (int i = 0; i < abs(endx - startx); i++) {
if (endx > startx) {
x += 1;
y += k;
}
else {
x -= 1;
y -= k;
}
glVertex2i(static_cast<int>(x), static_cast<int>(y+0.5)); //y四舍五入
}
}
else if (abs(k) > 1.0) {
for (int i = 0; i < abs(endy - starty); i++) {
if (endy > starty) {
y += 1;
x += 1.0/k;
}
else {
y -= 1;
x -= 1.0/k;
}
glVertex2i(static_cast<int>(x + 0.5), static_cast<int>(y)); //x四舍五入
}
}
}
else if (startx == endx) {//垂直画线
if (starty < endy) {
for (int i = starty; i < endy; i++) {
glVertex2i(startx, i);
}
}
else if (starty > endy) {
for (int i = endy; i < starty; i++) {
glVertex2i(startx, i);
}
}
}
else if (starty == endy) {//水平画线
if (startx < endx) {
for (int i = startx; i < endx; i++) {
glVertex2i(i, starty);
}
}
else if (startx > endx) {
for (int i = endx; i < startx; i++) {
glVertex2i(i, starty);
}
}
}
glFlush();
glEnd();
}

/*
中点画线算法实现
*/
/// <summary>
/// The Middle Point
/// Called TMP
/// </summary>
/// <param name="startx">起始位置x</param>
/// <param name="starty"></param>
/// <param name="endx">终止位置x</param>
/// <param name="endy"></param>
void TMP_Line(int startx, int starty, int endx, int endy) {
glBegin(GL_POINTS);
if (startx != endx && starty != endy)
{
bool kFlag = 0; //斜率是否大于1
int sFlag = 1; //斜率的正负
if (startx > endx) { //因为算法是x递增的,所以要保持起点x在终点左边
int tempx = startx, tempy = starty;
startx = endx, starty = endy;
endx = tempx, endy = tempy;
}
if (abs(starty - endy) > abs(startx - endx)) {
kFlag = true;
}
if (starty > endy) { //标记斜率小于零
sFlag = -1;
}
int a, b, TA, TAB, d, x, y;
if (sFlag == -1)
endy = starty + (starty - endy);

a = starty - endy;
b = endx - startx;
TA = 2 * a; //twoA
TAB = 2 * (a + b); //twoAB
d = 2 * a + b;
x = startx, y = starty;
if (!kFlag) {
for (int i = 0; i < (endx - startx); i++) {
if (d >= 0) {
glVertex2i(++x, y);
d += TA;
}
else {
glVertex2i(++x , y +=sFlag);
d += TAB;
}
}
}
else if (kFlag) {
if (kFlag == 1) {
TA = 2 * b;
d = 2 * b + a;
}
for (int i = 0; i < abs(endy - starty); i++) {
if (d >= 0) {
glVertex2i(++x , y +=sFlag);
d += TAB;
}
else {
glVertex2i(x, y+=sFlag);
d += TA;
}
}
}
}
else if (startx == endx) {//垂直画线
if (starty < endy) {
for (int i = starty; i < endy; i++) {
glVertex2i(startx, i);
}
}
else if (starty > endy) {
for (int i = endy; i < starty; i++) {
glVertex2i(startx, i);
}
}
}
else if (starty == endy) {//水平画线
if (startx < endx) {
for (int i = startx; i < endx; i++) {
glVertex2i(i, starty);
}
}
else if (startx > endx) {
for (int i = endx; i < startx; i++) {
glVertex2i(i, starty);
}
}
}
glFlush();
glEnd();
}

/*
Bresenham算法
这是图形学中用的最多的直线生成算法,全部是整数计算,加快了计算的速度
*/
/// <summary>
/// Bresenham
/// </summary>
/// <param name="startx"></param>
/// <param name="starty"></param>
/// <param name="endx"></param>
/// <param name="endy"></param>
void BRESENHAM_Line(int startx, int starty, int endx, int endy) {
glBegin(GL_POINTS);
if (startx != endx && starty != endy) {
bool kFlag = 0; //斜率是否大于1
int sFlag = 1; //斜率的正负
if (startx > endx) { //因为算法是x递增的,所以要保持起点x在终点左边
int tempx = startx, tempy = starty;
startx = endx, starty = endy;
endx = tempx, endy = tempy;
}
if (abs(starty - endy) > abs(startx - endx)) {
kFlag = true;
}
if (starty > endy) { //标记斜率小于零
sFlag = -1;
}
int x, y;
int dx, dy, p;
if (sFlag == -1)
endy = starty + (starty - endy);
dx = endx - startx;
dy = endy - starty;
x = startx, y = starty;
if (!kFlag) {
p = 2 * dy - dx;
for (int i = 0; i < (endx - startx); i++) {
if (p <= 0) {
glVertex2i(++x, y);
p += 2 * dy;
}
else {
glVertex2i(++x, y += sFlag);
p += 2 * dy - 2 * dx;
}
}
}
else {
p = 2 * dx - dy;
for (int i = 0;i < (endy - starty); i++) {
if (p <= 0) {
glVertex2i(x, y += sFlag);
p += 2 * dx;
}
else {
glVertex2i(++x, y += sFlag);
p += 2 * dx - 2 * dy;
}
}
}
}
else if (startx == endx) {//垂直画线
if (starty < endy) {
for (int i = starty; i < endy; i++) {
glVertex2i(startx, i);
}
}
else if (starty > endy) {
for (int i = endy; i < starty; i++) {
glVertex2i(startx, i);
}
}
}
else if (starty == endy) {//水平画线
if (startx < endx) {
for (int i = startx; i < endx; i++) {
glVertex2i(i, starty);
}
}
else if (startx > endx) {
for (int i = endx; i < startx; i++) {
glVertex2i(i, starty);
}
}
}
glFlush();
glEnd();
}

用于测试的一个主函数

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
/*
你可以使用左键绘制顶点
你可以使用右键删除顶点
直线的绘制沿着顶点顺序
*/
#include <gl/glut.h>
#include <iostream>
#include <list>
#include "DrawLine.hpp"
using namespace std;
#define m_POINT_SIZE 10
#define m_LINE_SIZE 2
list<pair<int, int >>Vertex;
void onDisplay();
void onReshape(int w, int h);
void onMouse(int button, int state, int x, int y);
void onReshape(int w, int h)
{
// 设置视口大小
glViewport(0, 0, w, h);
// 切换矩阵模式为投影矩阵
glMatrixMode(GL_PROJECTION);
// 载入单位矩阵
glLoadIdentity();
// 进行二维平行投影
gluOrtho2D(0, w, h, 0);
// 切换矩阵模式为模型矩阵
glMatrixMode(GL_MODELVIEW);
// 发送重绘
glutPostRedisplay();
}
void onMouse(int button, int state, int x, int y){
if (state == GLUT_DOWN) {
if (button == GLUT_LEFT_BUTTON)Vertex.push_back(make_pair(x, y));
else if (button == GLUT_RIGHT_BUTTON) {
auto ibeg = Vertex.begin();
while (ibeg != Vertex.end()) {
if (((x - ibeg->first) * (x - ibeg->first)) + ((y - ibeg->second) * (y - ibeg->second)) < 400) {
Vertex.erase(ibeg);
break;
}
ibeg++;
}
}
}
onDisplay();
}
void onDisplay() {
glClearColor(224 / 255.0, 237 / 255.0, 253 / 255.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0f, 0, 0);
auto ibeg = Vertex.begin(),jbeg=ibeg;
bool flag = false;
while (ibeg != Vertex.end()) {
glPointSize(m_POINT_SIZE);
glBegin(GL_POINTS);
glVertex2i(ibeg->first, ibeg->second);
glEnd();
glPointSize(m_LINE_SIZE);
if (!flag)
flag = true;
else {
//这里可以选择直线绘制方式
BRESENHAM_Line(ibeg->first, ibeg->second, jbeg->first, jbeg->second);
//TMP_Line(ibeg->first, ibeg->second, jbeg->first, jbeg->second);
//DDA_Line(ibeg->first, ibeg->second, jbeg->first, jbeg->second);
}
jbeg = ibeg;
ibeg++;
}
glutSwapBuffers();
}

int main(int argc, char* argv[])
{
// 初始化 glut
glutInit(&argc, argv);
// 设置 OpenGL 显示模式(双缓存, RGB 颜色模式)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
// 设置窗口初始尺寸
glutInitWindowSize(1000,800);
// 设置窗口初始位置
glutInitWindowPosition(0, 0);
// 设置窗口标题
glutCreateWindow("Terix");
glutReshapeFunc(onReshape);
glutDisplayFunc(onDisplay);
glutMouseFunc(onMouse);
// 进入 glut 事件循环
glutMainLoop();
return 0;
}

计算机图形学笔记一——绘制直线的算法
http://hexo.zhywzs.top/posts/30828/
作者
zhywzs
发布于
2023年4月21日
更新于
2025年10月1日
许可协议