line.cpp
2.7 KB
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
#include <kandinsky/line.h>
#include <kandinsky/pixel.h>
#include <assert.h>
void KDDrawLine(KDPoint p1, KDPoint p2, KDColor c) {
// Find the largest gap
KDPoint left, right;
if (p2.x > p1.x) {
left = p1;
right = p2;
} else {
left = p2;
right = p1;
}
KDPoint top, bottom;
if (p2.y > p1.y) {
top = p1;
bottom = p2;
} else {
top = p2;
bottom = p1;
}
assert(right.x >= left.x);
assert(bottom.y >= top.y);
KDCoordinate deltaX = 2*(right.x - left.x);
KDCoordinate deltaY = 2*(bottom.y - top.y);
KDPoint p, alwaysTranslate, conditionalTranslate;
KDCoordinate scanLength, error, minusError, plusError;
if (deltaX >= deltaY) {
p = left;
scanLength = right.x - left.x;
error = right.x - left.x;
minusError = deltaY;
plusError = deltaX;
alwaysTranslate = KDPointMake(1,0);
conditionalTranslate = KDPointMake(0, (right.y >= left.y ? 1 : -1));
} else {
p = top;
scanLength = bottom.y - top.y;
error = bottom.y - top.y;
minusError = deltaX;
plusError = deltaY;
alwaysTranslate = KDPointMake(0,1);
conditionalTranslate = KDPointMake((bottom.x >= top.x ? 1 : -1), 0);
}
KDCoordinate scanCounter = 0;
while (scanCounter++ < scanLength) {
KDSetPixel(p, c);
p = KDPointTranslate(p, alwaysTranslate);
error = error - minusError;
if (error <= 0) {
p = KDPointTranslate(p, conditionalTranslate);
error = error + plusError;
}
}
}
/*
#include <cmath>
#include <stdlib.h>
void KDDrawAntiAliasedLine(KDPoint p1, KDPoint p2, KDCoordinate width, KDColor frontColor, KDColor backColor) {
int x0 = p1.x;
int y0 = p1.y;
int x1 = p2.x;
int y1 = p2.y;
float wd = width;
int dx = abs(x1-x0), sx = x0 < x1 ? 1 : -1;
int dy = abs(y1-y0), sy = y0 < y1 ? 1 : -1;
int err = dx-dy, e2, x2, y2; // error value e_xy
float ed = dx+dy == 0 ? 1 : sqrt((float)dx*dx+(float)dy*dy);
for (wd = (wd+1)/2; ; ) { // pixel loop
KDPoint p = {.x = x0, .y = y0};
KDColor color = KDColorMix(KDColorRed, KDColorWhite, (abs(err-dx+dy)/ed-wd+1));
KDSetPixel(p, color);
e2 = err; x2 = x0;
if (2*e2 >= -dx) { // x step
for (e2 += dy, y2 = y0; e2 < ed*wd && (y1 != y2 || dx > dy); e2 += dx) {
y2 += sy;
p = {.x = x0, .y = y2};
color = KDColorMix(KDColorRed, KDColorWhite, (abs(err-dx+dy)/ed-wd+1));
setPixelColor(x0, y2 += sy, max(0,255*(abs(e2)/ed-wd+1)));
}
if (x0 == x1) break;
e2 = err; err -= dy; x0 += sx;
}
if (2*e2 <= dy) { // y step
for (e2 = dx-e2; e2 < ed*wd && (x1 != x2 || dx < dy); e2 += dy)
setPixelColor(x2 += sx, y0, max(0,255*(abs(e2)/ed-wd+1)));
if (y0 == y1) break;
err += dx; y0 += sy;
}
}
}
*/