Xiaolin Wu's line algorithm: Difference between revisions
Content added Content deleted
No edit summary |
(Updated D entry) |
||
Line 184: | Line 184: | ||
double x1, double y1, |
double x1, double y1, |
||
double x2, double y2, |
double x2, double y2, |
||
in Color color) |
in Color color) pure nothrow @safe @nogc { |
||
// Straight translation of Wikipedia pseudocode. |
// Straight translation of Wikipedia pseudocode. |
||
⚫ | |||
// std.math.round is not pure. ** |
|||
⚫ | |||
return floor(x + 0.5); |
return floor(x + 0.5); |
||
} |
} |
||
static double fpart(in double x) pure nothrow @safe { |
static double fpart(in double x) pure nothrow @safe @nogc { |
||
return x - x.floor; |
return x - x.floor; |
||
} |
} |
||
static double rfpart(in double x) pure nothrow @safe { |
static double rfpart(in double x) pure nothrow @safe @nogc { |
||
return 1 - fpart(x); |
return 1 - fpart(x); |
||
} |
} |
||
Line 215: | Line 217: | ||
// Plot function set here to handle the two cases of slope. |
// Plot function set here to handle the two cases of slope. |
||
void |
void function(ref Image!Color, in int, in int, in double, in Color) |
||
pure nothrow @safe @nogc plot; |
pure nothrow @safe @nogc plot; |
||
Line 222: | Line 224: | ||
swap(x2, y2); |
swap(x2, y2); |
||
swap(dx, dy); |
swap(dx, dy); |
||
//plot = (img, x, y, p) { |
//plot = (img, x, y, p, col) { |
||
plot = (ref |
plot = (ref img, x, y, p, col) { |
||
assert(p >= 0.0 && p <= 1.0); |
assert(p >= 0.0 && p <= 1.0); |
||
img[y, x] = mixColors( |
img[y, x] = mixColors(col, img[y, x], p); |
||
}; |
}; |
||
} else { |
} else { |
||
//plot = (img, x, y, p) { |
//plot = (img, x, y, p, col) { |
||
plot = (ref |
plot = (ref img, x, y, p, col) { |
||
assert(p >= 0.0 && p <= 1.0); |
assert(p >= 0.0 && p <= 1.0); |
||
img[x, y] = mixColors( |
img[x, y] = mixColors(col, img[x, y], p); |
||
}; |
}; |
||
} |
} |
||
Line 242: | Line 244: | ||
// Handle first endpoint. |
// Handle first endpoint. |
||
auto xEnd = |
auto xEnd = round(x1); |
||
auto yEnd = y1 + gradient * (xEnd - x1); |
auto yEnd = y1 + gradient * (xEnd - x1); |
||
auto xGap = rfpart(x1 + 0.5); |
auto xGap = rfpart(x1 + 0.5); |
||
Line 248: | Line 250: | ||
immutable xpxl1 = cast(int)xEnd; |
immutable xpxl1 = cast(int)xEnd; |
||
immutable ypxl1 = cast(int)yEnd.floor; |
immutable ypxl1 = cast(int)yEnd.floor; |
||
plot(img, xpxl1, ypxl1, rfpart(yEnd) * xGap); |
plot(img, xpxl1, ypxl1, rfpart(yEnd) * xGap, color); |
||
plot(img, xpxl1, ypxl1 + 1, fpart(yEnd) * xGap); |
plot(img, xpxl1, ypxl1 + 1, fpart(yEnd) * xGap, color); |
||
// First y-intersection for the main loop. |
// First y-intersection for the main loop. |
||
auto yInter = yEnd + gradient; |
auto yInter = yEnd + gradient; |
||
// Handle second endpoint. |
// Handle second endpoint. |
||
xEnd = |
xEnd = round(x2); |
||
yEnd = y2 + gradient * (xEnd - x2); |
yEnd = y2 + gradient * (xEnd - x2); |
||
xGap = fpart(x2 + 0.5); |
xGap = fpart(x2 + 0.5); |
||
Line 260: | Line 262: | ||
immutable xpxl2 = cast(int)xEnd; |
immutable xpxl2 = cast(int)xEnd; |
||
immutable ypxl2 = cast(int)yEnd.floor; |
immutable ypxl2 = cast(int)yEnd.floor; |
||
plot(img, xpxl2, ypxl2, rfpart(yEnd) * xGap); |
plot(img, xpxl2, ypxl2, rfpart(yEnd) * xGap, color); |
||
plot(img, xpxl2, ypxl2 + 1, fpart(yEnd) * xGap); |
plot(img, xpxl2, ypxl2 + 1, fpart(yEnd) * xGap, color); |
||
// Main loop. |
// Main loop. |
||
foreach (immutable x; xpxl1 + 1 .. xpxl2) { |
foreach (immutable x; xpxl1 + 1 .. xpxl2) { |
||
plot(img, x, cast(int)yInter.floor, rfpart(yInter)); |
plot(img, x, cast(int)yInter.floor, rfpart(yInter), color); |
||
plot(img, x, cast(int)yInter.floor + 1, fpart(yInter)); |
plot(img, x, cast(int)yInter.floor + 1, fpart(yInter), color); |
||
yInter += gradient; |
yInter += gradient; |
||
} |
} |