Skip to content

Commit 8fb38ba

Browse files
committed
Chapter 19 - Proper lines: remake
1 parent 6fe7b4b commit 8fb38ba

File tree

1 file changed

+34
-29
lines changed

1 file changed

+34
-29
lines changed

chapter-19/proper-lines.html

+34-29
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
function draw(pos, state, dispatch) {
88
let prev = pos;
99
function drawPixel(pos, state) {
10-
line(prev, pos, state, dispatch);
10+
const drawn = [{ x: pos.x, y: pos.y, color: state.color }, ...drawLine(prev, pos, state.color)];
11+
dispatch({ picture: state.picture.draw(drawn) });
1112
if (pos != prev) {
1213
prev = pos;
1314
}
@@ -16,37 +17,41 @@
1617
return drawPixel;
1718
}
1819

19-
const aroundDiag = [
20-
{ dx: -1, dy: 0 },
21-
{ dx: 1, dy: 0 },
22-
{ dx: 0, dy: -1 },
23-
{ dx: 0, dy: 1 },
24-
{ dx: -1, dy: -1 },
25-
{ dx: -1, dy: 1 },
26-
{ dx: 1, dy: -1 },
27-
{ dx: 1, dy: 1 },
28-
];
29-
30-
function line(start, end, state, dispatch) {
31-
const fullDistance = Math.floor(Math.sqrt((start.x - end.x) ** 2 + (start.y - end.y) ** 2));
32-
const drawn = [{ x: start.x, y: start.y, color: state.color, distance: fullDistance }];
33-
34-
for (let done = 0; done < drawn.length; done++) {
35-
const distances = [];
36-
for (let { dx, dy } of aroundDiag) {
37-
const x = drawn[done].x + dx;
38-
const y = drawn[done].y + dy;
39-
distances.push({ x, y, distance: Math.sqrt((x - end.x) ** 2 + (y - end.y) ** 2) });
20+
function drawLine(start, end, color) {
21+
const drawn = [];
22+
const xDiff = Math.abs(start.x - end.x);
23+
const yDiff = Math.abs(start.y - end.y);
24+
25+
if (xDiff > yDiff) {
26+
// horizontal-ish line
27+
if (start.x > end.x) {
28+
[start, end] = [end, start];
29+
}
30+
const m = (end.y - start.y) / (end.x - start.x);
31+
32+
for (let step = 1; step <= xDiff; step++) {
33+
drawn.push({ x: start.x + step, y: Math.floor(start.y + m * step), color });
34+
}
35+
} else {
36+
// vertical-ish line
37+
if (start.y > end.y) {
38+
[start, end] = [end, start];
4039
}
41-
const minDistance = distances.reduce(
42-
(min, curr) => (curr.distance < fullDistance && curr.distance < min.distance ? curr : min),
43-
distances[0]
44-
);
45-
if (drawn[done].distance > minDistance.distance) {
46-
drawn.push({ x: minDistance.x, y: minDistance.y, color: state.color, distance: minDistance.distance });
40+
const m = (end.x - start.x) / (end.y - start.y);
41+
42+
for (let step = 1; step <= yDiff; step++) {
43+
drawn.push({ x: Math.floor(start.x + m * step), y: start.y + step, color });
4744
}
4845
}
49-
dispatch({ picture: state.picture.draw(drawn) });
46+
47+
return drawn;
48+
}
49+
50+
function line(start, state, dispatch) {
51+
return (end) => {
52+
const drawn = drawLine(start, end, state.color);
53+
dispatch({ picture: state.picture.draw(drawn) });
54+
};
5055
}
5156

5257
let dom = startPixelEditor({

0 commit comments

Comments
 (0)