Sync
This commit is contained in:
parent
6f050a029e
commit
776bba907c
3887 changed files with 59894 additions and 7280 deletions
|
|
@ -1,27 +1,27 @@
|
|||
import std.math, std.algorithm, grayscale_image;
|
||||
|
||||
/// Plots anti-aliased line by Xiaolin Wu's line algorithm.
|
||||
void aaLine(Color)(ref Image!Color img, double x1, double y1,
|
||||
double x2, double y2,
|
||||
in Color color)
|
||||
/*pure*/ nothrow {
|
||||
void aaLine(Color)(ref Image!Color img,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
in Color color) /*pure*/ nothrow {
|
||||
// Straight translation of Wikipedia pseudocode.
|
||||
static double round(in double x) /*pure*/ nothrow {
|
||||
return floor(x + 0.5); // Not pure.
|
||||
static double round(in double x) pure nothrow {
|
||||
return floor(x + 0.5);
|
||||
}
|
||||
|
||||
static double fpart(in double x) /*pure*/ nothrow {
|
||||
return x - floor(x);
|
||||
static double fpart(in double x) pure nothrow {
|
||||
return x - x.floor;
|
||||
}
|
||||
|
||||
static double rfpart(in double x) /*pure*/ nothrow {
|
||||
static double rfpart(in double x) pure nothrow {
|
||||
return 1 - fpart(x);
|
||||
}
|
||||
|
||||
auto dx = x2 - x1;
|
||||
auto dy = y2 - y1;
|
||||
immutable ax = abs(dx);
|
||||
immutable ay = abs(dy);
|
||||
immutable ax = dx.abs;
|
||||
immutable ay = dy.abs;
|
||||
|
||||
static Color mixColors(in Color c1, in Color c2, in double p)
|
||||
pure nothrow {
|
||||
|
|
@ -35,17 +35,21 @@ void aaLine(Color)(ref Image!Color img, double x1, double y1,
|
|||
}
|
||||
|
||||
// Plot function set here to handle the two cases of slope.
|
||||
void delegate(in int, in int, in double) nothrow plot;
|
||||
void delegate(ref Image!Color img, in int, in int, in double)
|
||||
pure nothrow plot;
|
||||
|
||||
if (ax < ay) {
|
||||
swap(x1, y1);
|
||||
swap(x2, y2);
|
||||
swap(dx, dy);
|
||||
plot = (x, y, p) {
|
||||
//plot = (img, x, y, p) {
|
||||
plot = (ref Image!Color img, x, y, p) {
|
||||
assert(p >= 0.0 && p <= 1.0);
|
||||
img[y, x] = mixColors(color, img[y, x], p);
|
||||
};
|
||||
} else {
|
||||
plot = (x, y, p) {
|
||||
//plot = (img, x, y, p) {
|
||||
plot = (ref Image!Color img, x, y, p) {
|
||||
assert(p >= 0.0 && p <= 1.0);
|
||||
img[x, y] = mixColors(color, img[x, y], p);
|
||||
};
|
||||
|
|
@ -58,31 +62,31 @@ void aaLine(Color)(ref Image!Color img, double x1, double y1,
|
|||
immutable gradient = dy / dx;
|
||||
|
||||
// Handle first endpoint.
|
||||
auto xEnd = round(x1);
|
||||
auto xEnd = x1.round; // Not pure.
|
||||
auto yEnd = y1 + gradient * (xEnd - x1);
|
||||
auto xGap = rfpart(x1 + 0.5);
|
||||
// This will be used in the main loop.
|
||||
immutable xpxl1 = cast(int)xEnd;
|
||||
immutable ypxl1 = cast(int)floor(yEnd);
|
||||
plot(xpxl1, ypxl1, rfpart(yEnd) * xGap);
|
||||
plot(xpxl1, ypxl1 + 1, fpart(yEnd) * xGap);
|
||||
immutable ypxl1 = cast(int)yEnd.floor;
|
||||
plot(img, xpxl1, ypxl1, rfpart(yEnd) * xGap);
|
||||
plot(img, xpxl1, ypxl1 + 1, fpart(yEnd) * xGap);
|
||||
// First y-intersection for the main loop.
|
||||
auto yInter = yEnd + gradient;
|
||||
|
||||
// Handle second endpoint.
|
||||
xEnd = round(x2);
|
||||
xEnd = x2.round;
|
||||
yEnd = y2 + gradient * (xEnd - x2);
|
||||
xGap = fpart(x2 + 0.5);
|
||||
// This will be used in the main loop.
|
||||
immutable xpxl2 = cast(int)xEnd;
|
||||
immutable ypxl2 = cast(int)floor(yEnd);
|
||||
plot(xpxl2, ypxl2, rfpart(yEnd) * xGap);
|
||||
plot(xpxl2, ypxl2 + 1, fpart(yEnd) * xGap);
|
||||
immutable ypxl2 = cast(int)yEnd.floor;
|
||||
plot(img, xpxl2, ypxl2, rfpart(yEnd) * xGap);
|
||||
plot(img, xpxl2, ypxl2 + 1, fpart(yEnd) * xGap);
|
||||
|
||||
// Main loop.
|
||||
foreach (immutable x; xpxl1 + 1 .. xpxl2) {
|
||||
plot(x, cast(int)floor(yInter), rfpart(yInter));
|
||||
plot(x, cast(int)floor(yInter) + 1, fpart(yInter));
|
||||
plot(img, x, cast(int)yInter.floor, rfpart(yInter));
|
||||
plot(img, x, cast(int)yInter.floor + 1, fpart(yInter));
|
||||
yInter += gradient;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
#lang racket
|
||||
(require 2htdp/image)
|
||||
|
||||
(define (plot img x y c)
|
||||
(define c*255 (exact-round (* (- 1 c) 255)))
|
||||
(place-image
|
||||
(rectangle 1 1 'solid (make-color c*255 c*255 c*255 255))
|
||||
x y img))
|
||||
|
||||
(define ipart exact-floor) ; assume that a "round-down" is what we want when -ve
|
||||
;;; `round` is built in -- but we'll use exact round (and I'm not keen on over-binding round)
|
||||
|
||||
(define (fpart n) (- n (exact-floor n)))
|
||||
(define (rfpart n) (- 1 (fpart n)))
|
||||
|
||||
(define (draw-line img x0 y0 x1 y1)
|
||||
(define (draw-line-steeped img x0 y0 x1 y1 steep?)
|
||||
(define (draw-line-steeped-l-to-r img x0 y0 x1 y1 steep?)
|
||||
(define dx (- x1 x0))
|
||||
(define dy (- y1 y0))
|
||||
(define gradient (/ dy dx))
|
||||
|
||||
(define (handle-end-point img x y)
|
||||
(define xend (exact-round x))
|
||||
(define yend (+ y (* gradient (- xend x))))
|
||||
(define xgap (rfpart (+ x 0.5)))
|
||||
(define ypxl (ipart yend))
|
||||
(define intery (+ yend gradient))
|
||||
|
||||
(case steep?
|
||||
[(#t)
|
||||
(define img* (plot img ypxl xend (* xgap (rfpart yend))))
|
||||
(values (plot img* (+ ypxl 1) xend (* xgap (fpart yend))) xend intery)]
|
||||
[(#f)
|
||||
(define img* (plot img xend ypxl (* xgap (rfpart yend))))
|
||||
(values (plot img* xend (+ ypxl 1) (* xgap (fpart yend))) xend intery)]))
|
||||
|
||||
(define-values (img-with-l-endpoint xpl1 intery) (handle-end-point img x0 y0))
|
||||
(define-values (img-with-r-endpoint xpl2 _) (handle-end-point img-with-l-endpoint x1 y1))
|
||||
|
||||
(for/fold ((img img-with-l-endpoint) (y intery))
|
||||
((x (in-range (+ xpl1 1) xpl2)))
|
||||
(define y-i (ipart y))
|
||||
(values
|
||||
(case steep?
|
||||
[(#t)
|
||||
(define img* (plot img y-i x (rfpart y)))
|
||||
(plot img* (+ 1 y-i) x (fpart y))]
|
||||
[(#f)
|
||||
(define img* (plot img x y-i (rfpart y)))
|
||||
(plot img* x (+ 1 y-i) (fpart y))])
|
||||
(+ y gradient))))
|
||||
|
||||
(if (> x0 x1)
|
||||
(draw-line-steeped-l-to-r img x1 y1 x0 y0 steep?)
|
||||
(draw-line-steeped-l-to-r img x0 y0 x1 y1 steep?)))
|
||||
|
||||
(define steep? (> (abs (- y1 y0)) (abs (- x1 x0))))
|
||||
(define-values (img* _)
|
||||
(if steep?
|
||||
(draw-line-steeped img y0 x0 y1 x1 steep?)
|
||||
(draw-line-steeped img x0 y0 x1 y1 steep?)))
|
||||
img*)
|
||||
|
||||
(define img-1
|
||||
(beside
|
||||
(scale 3 (draw-line (empty-scene 150 100) 12 12 138 88))
|
||||
(above
|
||||
(scale 1 (draw-line (empty-scene 150 100) 12 50 138 50))
|
||||
(scale 1 (draw-line (empty-scene 150 100) 75 12 75 88))
|
||||
(scale 1 (draw-line (empty-scene 150 100) 12 88 138 12)))))
|
||||
|
||||
(define img-2
|
||||
(beside
|
||||
(scale 3 (draw-line (empty-scene 100 150) 12 12 88 138))
|
||||
(above (scale 1 (draw-line (empty-scene 100 150) 50 12 50 138))
|
||||
(scale 1 (draw-line (empty-scene 100 150) 12 75 88 75))
|
||||
(scale 1 (draw-line (empty-scene 100 150) 88 12 12 138)))))
|
||||
|
||||
img-1
|
||||
img-2
|
||||
(save-image img-1 "images/xiaolin-wu-racket-1.png")
|
||||
(save-image img-2 "images/xiaolin-wu-racket-2.png")
|
||||
Loading…
Add table
Add a link
Reference in a new issue