Source Code for Wall (2022)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn adjust-flow-points | |
[flow-points disturbance-x disturbance-y disturbance-radius disturbance-theta] | |
(for [[x y theta] flow-points] | |
(let [disturbance-dist (q/dist disturbance-x disturbance-y x y) | |
theta-adjust (if (> disturbance-dist disturbance-radius) | |
0 | |
(rescale disturbance-dist 0 disturbance-radius disturbance-theta 0)) | |
; final-theta (min (pi 0.72) (max (pi 0.45) (+ theta theta-adjust))) | |
final-theta (+ theta theta-adjust)] | |
[x y final-theta]))) | |
(defn get-flow-points | |
[default-theta spacing left-x right-x top-y bot-y] | |
(let [flow-points (for [y (range top-y bot-y spacing) | |
x (range left-x right-x spacing)] | |
[x y default-theta])] | |
(loop [n 30 | |
flow-points flow-points] | |
(if (zero? n) | |
(vec flow-points) | |
(let [disturbance-x (q/random left-x right-x) | |
disturbance-y (q/random top-y bot-y) | |
disturbance-theta (gauss 0 (pi 0.0095)) | |
disturbance-radius (max (w 0.1) (abs-gauss (w 0.60) (w 0.25))) | |
adjusted (adjust-flow-points flow-points | |
disturbance-x disturbance-y | |
disturbance-radius disturbance-theta)] | |
(recur (dec n) adjusted)))))) | |
(defn draw-dirty-dot | |
[x y radius skew? skew-mean-theta] | |
(let [starting-theta (q/random 0 (pi 2.0)) | |
skew-theta (mod (gauss skew-mean-theta (pi 0.2)) (pi 1.0)) | |
skew-ratio (if skew? | |
(gauss 0.0 0.6) | |
0)] | |
(q/begin-shape) | |
(loop [theta starting-theta] | |
(if (> theta (+ starting-theta (pi 2.0))) | |
(apply q/curve-vertex (angular-coords x y starting-theta radius)) | |
(let [angle-dist (mod (q/abs (- theta skew-theta)) (pi 1.0)) | |
skew-modifier (rescale angle-dist 0.0 (pi 1.0) (+ 1.0 skew-ratio) (- 1.0 skew-ratio)) | |
noisy-radius (if (= starting-theta theta) | |
radius | |
(gauss radius (* radius 0.15))) | |
exact-radius (* noisy-radius skew-modifier)] | |
(apply q/curve-vertex (angular-coords x y theta exact-radius)) | |
(recur (+ theta (abs-gauss (pi 0.1) (pi 0.02))))))) | |
(q/end-shape :close))) | |
(defn fill-brick | |
[y overlay-graphics & [vertical?]] | |
(let [hue (mod (rescale y 0 (h) 220 385) 360) | |
; dimmer close to ground | |
ground-d (Math/pow (/ (- (h) y) (h)) 2) | |
bright-adjust (min 0.0 | |
(max -2.0 (rescale ground-d | |
0 0.03 | |
0.0 0))) | |
; slightly dimmer close to top | |
top-d (Math/pow (/ y (h)) 2) | |
bright-adjust-2 (min 0.0 | |
(max -2.7 (rescale top-d | |
0 0.07 | |
-2.3 0))) | |
sat-adjust (max 0 (rescale ground-d | |
0 0.03 | |
2.0 0)) | |
sat-adjust-2 (min 0.0 | |
(max -1.0 (rescale top-d | |
0 0.05 | |
-1.0 0))) | |
mid-bright (gauss (+ 87 bright-adjust bright-adjust-2) 0.5) | |
step (case detail-level | |
:low (w 0.005) | |
:med (w 0.001) | |
:high (w 0.0002)) | |
rect-len (* step 1.5) | |
x-noise-scale (max (w 0.005) (gauss (w 0.014) (w 0.001))) | |
y-noise-scale (max (w 0.005) (gauss (w 0.014) (w 0.001))) | |
noise-offset (q/random 0 (w 25.0))] | |
(q/with-graphics overlay-graphics | |
(q/background hue (+ 0.5 sat-adjust sat-adjust-2) mid-bright) | |
(q/no-stroke) | |
(let [x-end (if vertical? (h 0.031) (w 0.0501)) | |
y-end (if vertical? (w 0.0501) (h 0.031))] | |
(doseq [x1 (range 0 x-end step) | |
y1 (range 0 y-end step)] | |
(let [[x2 y2] (angular-coords x1 y1 (pi -0.23) (w 0.001)) | |
n1 (q/noise (/ (+ x1 noise-offset) x-noise-scale) (/ y1 y-noise-scale)) | |
n2 (q/noise (/ (+ x2 noise-offset) x-noise-scale) (/ y2 y-noise-scale)) | |
height-diff (- n1 n2) | |
light-bright-adjust (if (< height-diff 0) | |
(* -1.0 (Math/pow (rescale height-diff 0.0 -1.0 0.0 40.0) 1.65)) | |
(* 1.0 (Math/pow (rescale height-diff 0.0 1.0 0.0 30.0) 1.65))) | |
light-bright-adjust (min 6 (max -20 light-bright-adjust)) | |
final-bright (gauss | |
(min 97 | |
(+ mid-bright light-bright-adjust)) | |
0.6)] | |
(q/fill hue (+ 0.5 sat-adjust sat-adjust-2) final-bright) | |
(q/rect x1 y1 rect-len rect-len))))))) | |
(defn drop-curve-before-intersection-with-line | |
[curve p1 p2] | |
(loop [curve curve] | |
(if (< (count curve) 2) | |
nil | |
(let [[seg-start seg-end] (take 2 curve) | |
inter (lines-intersection-point | |
p1 p2 | |
seg-start seg-end)] | |
(if inter | |
(concat [inter] (rest curve)) | |
(recur (rest curve))))))) | |
(defn draw-brick | |
[x y | |
brick-width brick-height | |
grout-horizontal grout-vertical | |
overlay-graphics mask-graphics shadow-mask-graphics | |
get-offset] | |
(let [[brick-shift-x brick-shift-y] (get-offset x y) | |
mask-offset (w 0.005) | |
[top-right-x-off top-right-y-off] (get-offset (+ x brick-width) y) | |
ang (angle brick-shift-x brick-shift-y (+ brick-width top-right-x-off) top-right-y-off) | |
rotation (gauss ang (pi 0.0015)) | |
y-shift (gauss brick-shift-y (w 0.00004)) | |
x-shift (gauss brick-shift-x (w 0.00004)) | |
x (+ x x-shift) | |
y (+ y y-shift) | |
top-left-x mask-offset | |
top-left-y mask-offset | |
top-right (angular-coords top-left-x top-left-y rotation brick-width) | |
bot-left (angular-coords top-left-x top-left-y (+ rotation (pi 0.5)) brick-height) | |
bot-right (angular-coords (first bot-left) (second bot-left) rotation brick-width) | |
curve-variance (w 0.000045) | |
top-curve (concat | |
(let [t (gauss 0.0 0.005) | |
x (interpolate top-left-x (first top-right) t) | |
y (interpolate top-left-y (second top-right) t)] | |
[[x y]]) | |
(for [t (range 0.1 0.91 0.1)] | |
(let [final-t (gauss t 0.02) | |
x (interpolate top-left-x (first top-right) final-t) | |
y (interpolate top-left-y (second top-right) final-t)] | |
[x (gauss y curve-variance)])) | |
(let [t (gauss 1.0 0.005) | |
x (interpolate top-left-x (first top-right) t) | |
y (interpolate top-left-y (second top-right) t)] | |
[[x y]])) | |
right-curve (concat | |
(for [t (range 0.2 0.81 0.2)] | |
(let [final-t (gauss t 0.03) | |
x (interpolate (first top-right) (first bot-right) final-t) | |
y (interpolate (second top-right) (second bot-right) final-t)] | |
[(gauss x curve-variance) y])) | |
(let [t (gauss 1.0 0.01) | |
x (interpolate (first top-right) (first bot-right) t) | |
y (interpolate (second top-right) (second bot-right) t)] | |
[[x y]])) | |
bot-curve (concat | |
(for [t (range 0.1 0.91 0.1)] | |
(let [final-t (gauss t 0.02) | |
x (interpolate (first bot-right) (first bot-left) final-t) | |
y (interpolate (second bot-right) (second bot-left) final-t)] | |
[x (gauss y curve-variance)])) | |
(let [t (gauss 1.0 0.005) | |
x (interpolate (first bot-right) (first bot-left) t) | |
y (interpolate (second bot-right) (second bot-left) t)] | |
[[x y]])) | |
left-curve (for [t (range 0.2 0.81 0.2)] | |
(let [final-t (gauss t 0.03) | |
x (interpolate (first bot-left) top-left-x final-t) | |
y (interpolate (second bot-left) top-left-y final-t)] | |
[(gauss x curve-variance) y]))] | |
(q/with-graphics mask-graphics | |
(q/background 0 0 0) | |
(q/begin-shape) | |
(doseq [[x y] (concat top-curve right-curve bot-curve left-curve)] | |
(q/vertex x y)) | |
(q/end-shape :close)) | |
(fill-brick y overlay-graphics false) | |
(.mask overlay-graphics mask-graphics) | |
(q/image overlay-graphics | |
(- x mask-offset) (- y mask-offset) | |
(+ brick-width grout-vertical (w 0.01)) | |
(+ brick-height grout-horizontal (w 0.01))) | |
(q/stroke-cap :square) | |
; top highlight | |
(q/stroke 40 0 100 (max 0 (gauss 0.2 0.1))) | |
(q/stroke-weight (max (w 0.0001) (gauss (w 0.0005) (w 0.0001)))) | |
(q/no-fill) | |
(q/begin-shape) | |
(doseq [[inner-x inner-y] top-curve] | |
(let [final-x (+ x inner-x (* mask-offset -1.0)) | |
final-y (+ y inner-y (* mask-offset -1.0))] | |
(q/vertex final-x (+ final-y (w 0.0003))))) | |
(q/end-shape) | |
; right highlight | |
(q/stroke 40 0 100 (max 0 (gauss 0.35 0.05))) | |
(q/stroke-weight (max (w 0.0001) (gauss (w 0.0007) (w 0.00015)))) | |
(q/begin-shape) | |
(doseq [[inner-x inner-y] (concat (take-last 1 top-curve) right-curve)] | |
(let [final-x (+ x inner-x (* mask-offset -1.0)) | |
final-y (+ y inner-y (* mask-offset -1.0))] | |
(q/vertex (- final-x (w 0.0003)) final-y))) | |
(q/end-shape) | |
; cast shadow | |
(q/with-graphics shadow-mask-graphics | |
(let [shadow-thick (max 0 (gauss (w 0.0018) (w 0.0006))) | |
noise-offset (q/random 0 (w 200.0)) | |
bot-points (concat (take-last 1 right-curve) bot-curve) | |
bot-points-and-thicknesses (for [[x y] bot-points] | |
(let [n (q/noise (/ (+ x noise-offset) (w 0.05)) (/ y (w 0.03))) | |
n (rescale n 0.0 1.0 -0.25 1.0) | |
thick (max 0 (* n shadow-thick))] | |
[[x y] thick])) | |
left-points (concat left-curve (take 1 top-curve)) | |
left-points-and-thicknesses (for [[x y] left-points] | |
(let [n (q/noise (/ (+ x noise-offset) (w 0.05)) (/ y (w 0.03))) | |
n (rescale n 0.0 1.0 -0.35 1.0) | |
thick (max 0 (* n shadow-thick))] | |
[[x y] thick])) | |
shadow-left-full (for [[[x y] thick] (reverse left-points-and-thicknesses)] | |
(angular-coords x y (pi 0.85) thick)) | |
shadow-left-shrunk (for [[[x y] thick] (reverse left-points-and-thicknesses)] | |
(angular-coords x y (pi 0.85) (* thick 0.6))) | |
shadow-bot-full (for [[[x y] thick] (reverse bot-points-and-thicknesses)] | |
(angular-coords x y (pi 0.85) thick)) | |
shadow-bot-shrunk (for [[[x y] thick] (reverse bot-points-and-thicknesses)] | |
(angular-coords x y (pi 0.85) (* thick 0.6)))] | |
(q/no-stroke) | |
; outer softer edge of shadow | |
(q/fill 0 0 40) | |
(q/begin-shape) | |
(doseq [[inner-x inner-y] (concat bot-points left-points shadow-left-full shadow-bot-full)] | |
(let [final-x (+ x inner-x (* mask-offset -1.0)) | |
final-y (+ y inner-y (* mask-offset -1.0))] | |
(q/vertex final-x final-y))) | |
(q/end-shape :close) | |
; inner deep shadow | |
(q/fill 0 0 65) | |
(q/begin-shape) | |
(doseq [[inner-x inner-y] (concat bot-points left-points shadow-left-shrunk shadow-bot-shrunk)] | |
(let [final-x (+ x inner-x (* mask-offset -1.0)) | |
final-y (+ y inner-y (* mask-offset -1.0))] | |
(q/vertex final-x final-y))) | |
(q/end-shape :close))) | |
; does the brick sit in the cast shadow? | |
(when (and (< x (w 0.4185)) | |
(> (+ x brick-width) (w 0.4195))) | |
(let [p1 [(w 0.4187) (- y (h 0.005))] | |
p2 [(w 0.4187) (+ y brick-height (h 0.005))] | |
finalized-top (for [[inner-x inner-y] top-curve] | |
(let [final-x (+ x inner-x (* mask-offset -1.0)) | |
final-y (+ y inner-y (* mask-offset -1.0))] | |
[final-x final-y])) | |
finalized-right (for [[inner-x inner-y] right-curve] | |
(let [final-x (+ x inner-x (* mask-offset -1.0)) | |
final-y (+ y inner-y (* mask-offset -1.0))] | |
[final-x final-y])) | |
finalized-bottom (for [[inner-x inner-y] bot-curve] | |
(let [final-x (+ x inner-x (* mask-offset -1.0)) | |
final-y (+ y inner-y (* mask-offset -1.0))] | |
[final-x final-y])) | |
trimmed-top (drop-curve-before-intersection-with-line finalized-top p1 p2) | |
trimmed-bot (reverse | |
(drop-curve-before-intersection-with-line | |
(reverse finalized-bottom) | |
p1 p2)) | |
base-x-offset (abs-gauss 0 (w 0.0005)) | |
noise-y-offset (q/random 0 (h 4.0)) | |
y-noise-scale (h 0.025)] | |
(when (not (seq trimmed-top)) | |
(println "no trimmed top")) | |
(when (not (seq trimmed-bot)) | |
(println "no trimmed bot")) | |
(when (and (seq trimmed-top) | |
(seq trimmed-bot)) | |
(q/with-graphics shadow-mask-graphics | |
(q/fill 0 0 0) | |
(q/begin-shape) | |
(doseq [[inner-x inner-y] (concat top-curve right-curve bot-curve left-curve)] | |
(let [final-x (+ x inner-x (* mask-offset -1.0)) | |
final-y (+ y inner-y (* mask-offset -1.0))] | |
(q/vertex final-x final-y))) | |
(q/end-shape :close) | |
(q/stroke-weight (w 0.0004)) | |
; outer soft shadow | |
(q/fill 0 0 50) | |
(q/stroke 0 0 50) | |
(q/begin-shape) | |
(doseq [p (concat (drop 2 trimmed-top) finalized-right (drop-last 2 trimmed-bot))] | |
(apply q/vertex p)) | |
(let [[top-x top-y] (first trimmed-top) | |
[bot-x bot-y] (last trimmed-bot)] | |
(doseq [t (range 0.0 1.01 0.05)] | |
(let [x (interpolate bot-x top-x t) | |
y (interpolate bot-y top-y t) | |
n (q/noise (/ (+ y noise-y-offset) y-noise-scale)) | |
x-offset (rescale n 0.0 1.0 0 (w 0.0015))] | |
(q/vertex (+ x x-offset base-x-offset (w -0.0003)) y)))) | |
(q/end-shape :close) | |
; inner dark shadow | |
(q/fill 0 0 75) | |
(q/stroke 0 0 75) | |
(q/begin-shape) | |
(doseq [p (concat (drop 2 trimmed-top) finalized-right (drop-last 2 trimmed-bot))] | |
(apply q/vertex p)) | |
(let [[top-x top-y] (first trimmed-top) | |
[bot-x bot-y] (last trimmed-bot)] | |
(doseq [t (range 0.0 1.01 0.05)] | |
(let [x (interpolate bot-x top-x t) | |
y (interpolate bot-y top-y t) | |
n (q/noise (/ (+ y noise-y-offset) y-noise-scale)) | |
x-offset (rescale n 0.0 1.0 0 (w 0.0015))] | |
(q/vertex (+ x x-offset base-x-offset (w 0.0002)) y)))) | |
(q/end-shape :close) | |
(q/no-stroke))))))) | |
(defn draw-brick-vertical | |
[x y brick-width brick-height | |
grout-horizontal grout-vertical | |
overlay-graphics mask-graphics shadow-mask-graphics] | |
(let [mask-offset (w 0.005) | |
rotation (gauss 0 (pi 0.0017)) | |
y-shift (gauss 0 (w 0.00004)) | |
x-shift (gauss 0 (w 0.00004)) | |
x (+ x x-shift) | |
y (+ y y-shift) | |
top-left-x mask-offset | |
top-left-y mask-offset | |
top-right (angular-coords top-left-x top-left-y rotation brick-width) | |
bot-left (angular-coords top-left-x top-left-y (+ rotation (pi 0.5)) brick-height) | |
bot-right (angular-coords (first bot-left) (second bot-left) rotation brick-width) | |
curve-variance (w 0.000045) | |
top-curve (concat | |
(let [t (gauss 0.0 0.01) | |
x (interpolate top-left-x (first top-right) t) | |
y (interpolate top-left-y (second top-right) t)] | |
[[x y]]) | |
(for [t (range 0.2 0.81 0.2)] | |
(let [final-t (gauss t 0.03) | |
x (interpolate top-left-x (first top-right) final-t) | |
y (interpolate top-left-y (second top-right) final-t)] | |
[x (gauss y curve-variance)])) | |
(let [t (gauss 1.0 0.01) | |
x (interpolate top-left-x (first top-right) t) | |
y (interpolate top-left-y (second top-right) t)] | |
[[x y]])) | |
right-curve (concat | |
(for [t (range 0.1 0.91 0.1)] | |
(let [final-t (gauss t 0.02) | |
x (interpolate (first top-right) (first bot-right) final-t) | |
y (interpolate (second top-right) (second bot-right) final-t)] | |
[(gauss x curve-variance) y])) | |
(let [t (gauss 1.0 0.005) | |
x (interpolate (first top-right) (first bot-right) t) | |
y (interpolate (second top-right) (second bot-right) t)] | |
[[x y]])) | |
bot-curve (concat | |
(for [t (range 0.2 0.81 0.2)] | |
(let [final-t (gauss t 0.03) | |
x (interpolate (first bot-right) (first bot-left) final-t) | |
y (interpolate (second bot-right) (second bot-left) final-t)] | |
[x (gauss y curve-variance)])) | |
(let [t (gauss 1.0 0.01) | |
x (interpolate (first bot-right) (first bot-left) t) | |
y (interpolate (second bot-right) (second bot-left) t)] | |
[[x y]])) | |
left-curve (for [t (range 0.1 0.91 0.1)] | |
(let [final-t (gauss t 0.02) | |
x (interpolate (first bot-left) top-left-x final-t) | |
y (interpolate (second bot-left) top-left-y final-t)] | |
[(gauss x curve-variance) y]))] | |
(q/with-graphics mask-graphics | |
(q/background 0 0 0) | |
(q/begin-shape) | |
(doseq [[x y] (concat top-curve right-curve bot-curve left-curve)] | |
(q/vertex x y)) | |
(q/end-shape :close)) | |
(fill-brick y overlay-graphics true) | |
(.mask overlay-graphics mask-graphics) | |
(q/image overlay-graphics | |
(- x mask-offset) (- y mask-offset) | |
(+ brick-width grout-vertical (w 0.01)) | |
(+ brick-height grout-horizontal (w 0.01))) | |
(q/stroke-cap :square) | |
; top highlight | |
(q/stroke 40 2 100 (max 0 (gauss 0.4 0.1))) | |
(q/stroke-weight (max (w 0.0001) (gauss (w 0.0005) (w 0.00015)))) | |
(q/no-fill) | |
(q/begin-shape) | |
(doseq [[inner-x inner-y] top-curve] | |
(let [final-x (+ x inner-x (* mask-offset -1.0)) | |
final-y (+ y inner-y (* mask-offset -1.0))] | |
(q/vertex final-x (+ final-y (w 0.0004))))) | |
(q/end-shape) | |
; right highlight | |
(q/stroke 40 2 100 (max 0 (gauss 0.5 0.1))) | |
(q/stroke-weight (max (w 0.0001) (gauss (w 0.0005) (w 0.00015)))) | |
(q/begin-shape) | |
(doseq [[inner-x inner-y] (concat (take-last 1 top-curve) right-curve)] | |
(let [final-x (+ x inner-x (* mask-offset -1.0)) | |
final-y (+ y inner-y (* mask-offset -1.0))] | |
(q/vertex (- final-x (w 0.0004)) final-y))) | |
(q/end-shape) | |
; cast shadow | |
(q/with-graphics shadow-mask-graphics | |
(let [shadow-thick (max 0 (gauss (w 0.0019) (w 0.0005))) | |
noise-offset (q/random 0 (w 200.0)) | |
bot-points (concat (take-last 1 right-curve) bot-curve) | |
bot-points-and-thicknesses (for [[x y] bot-points] | |
(let [n (q/noise (/ (+ x noise-offset) (w 0.05)) (/ y (w 0.03))) | |
n (rescale n 0.0 1.0 -0.1 1.0) | |
thick (max 0 (* n shadow-thick))] | |
[[x y] thick])) | |
left-points (concat left-curve (take 1 top-curve)) | |
left-points-and-thicknesses (for [[x y] left-points] | |
(let [n (q/noise (/ (+ x noise-offset) (w 0.05)) (/ y (w 0.03))) | |
n (rescale n 0.0 1.0 -0.4 1.0) | |
thick (max 0 (* n shadow-thick))] | |
[[x y] thick])) | |
shadow-left-full (for [[[x y] thick] (reverse left-points-and-thicknesses)] | |
(angular-coords x y (pi 0.85) thick)) | |
shadow-left-shrunk (for [[[x y] thick] (reverse left-points-and-thicknesses)] | |
(angular-coords x y (pi 0.85) (* thick 0.6))) | |
shadow-bot-full (for [[[x y] thick] (reverse bot-points-and-thicknesses)] | |
(angular-coords x y (pi 0.85) thick)) | |
shadow-bot-shrunk (for [[[x y] thick] (reverse bot-points-and-thicknesses)] | |
(angular-coords x y (pi 0.85) (* thick 0.6)))] | |
(q/no-stroke) | |
; outer soft edge of shadow | |
(q/fill 0 0 40) | |
(q/begin-shape) | |
(doseq [[inner-x inner-y] (concat bot-points left-points shadow-left-full shadow-bot-full)] | |
(let [final-x (+ x inner-x (* mask-offset -1.0)) | |
final-y (+ y inner-y (* mask-offset -1.0))] | |
(q/vertex final-x final-y))) | |
(q/end-shape :close) | |
; outer soft edge of shadow | |
(q/fill 0 0 65) | |
(q/begin-shape) | |
(doseq [[inner-x inner-y] (concat bot-points left-points shadow-left-shrunk shadow-bot-shrunk)] | |
(let [final-x (+ x inner-x (* mask-offset -1.0)) | |
final-y (+ y inner-y (* mask-offset -1.0))] | |
(q/vertex final-x final-y))) | |
(q/end-shape :close))))) | |
(defn color-grout | |
[full-width] | |
(q/no-stroke) | |
(doseq [x (range 0 full-width (w 0.005)) | |
y (range 0 (h 1.02) (w 0.005))] | |
(let [n (q/noise (/ x (w 0.15)) (/ y (w 0.15))) | |
mean-bright (if (< y (h 0.5)) | |
(rescale y 0 (h 0.5) 68 56) | |
(rescale y (h 0.5) (h) 56 60)) | |
bright-adjust (rescale n 0.0 1.0 -19.0 8.0) | |
ground-d (Math/pow (/ (- (h) y) (h)) 2) | |
bright-adjust-2 (max 0 (rescale ground-d | |
0 0.05 | |
6 0)) | |
sat-adjust (max 0 (rescale ground-d | |
0 0.05 | |
3 0))] | |
(q/fill 20 sat-adjust (+ mean-bright bright-adjust bright-adjust-2)) | |
(q/rect x y (w 0.011) (w 0.011)))) | |
; big splotches | |
(let [num-iterations (case detail-level | |
:low 0 | |
:med 10500 | |
:high 70000)] | |
(dotimes [_ (* num-iterations (/ full-width (w)))] | |
(let [x (q/random (w -0.01) (w 1.01)) | |
y (q/random (h -0.01) (h 1.01)) | |
n (q/noise (/ x (w 0.005)) (/ y (w 0.005))) | |
mean-bright (if (< y (h 0.5)) | |
(rescale y 0 (h 0.5) 68 56) | |
(rescale y (h 0.5) (h) 56 58)) | |
bright-adjust (rescale n 0.0 1.0 -19.0 8.0) | |
ground-d (Math/pow (/ (- (h) y) (h)) 2) | |
bright-adjust-2 (max 0 (rescale ground-d | |
0 0.05 | |
6 0)) | |
final-bright (gauss (+ mean-bright bright-adjust bright-adjust-2) 2) | |
sat-adjust (max 0 (rescale ground-d | |
0 0.05 | |
3 0)) | |
alpha (min 1.0 (gauss 0.5 0.3)) | |
big? true | |
e-width (if big? | |
(max (w 0.0005) (gauss (w 0.0025) (w 0.003))) | |
(max (w 0.0001) (gauss (w 0.0004) (w 0.0002)))) | |
e-height (* e-width (gauss 1.0 0.2))] | |
(q/fill (gauss 25 2) | |
(max 0 (gauss sat-adjust 1)) | |
final-bright | |
alpha) | |
(if (> e-width (w 0.0004)) | |
(draw-dirty-dot x y (/ e-width 2.0) true 0) | |
(q/ellipse x y e-width e-height))))) | |
; small splotches | |
(let [num-iterations (case detail-level | |
:low 0 | |
:med 150000 | |
:high 1500000)] | |
(dotimes [_ (* num-iterations (/ full-width (w)))] | |
(let [x (q/random (w -0.01) (w 1.01)) | |
y (q/random (h -0.01) (h 1.01)) | |
n (q/noise (/ x (w 0.005)) (/ y (w 0.005))) | |
mean-bright (if (< y (h 0.5)) | |
(rescale y 0 (h 0.5) 68 56) | |
(rescale y (h 0.5) (h) 56 58)) | |
bright-adjust (rescale n 0.0 1.0 -19.0 8.0) | |
ground-d (Math/pow (/ (- (h) y) (h)) 2) | |
bright-adjust-2 (max 0 (rescale ground-d | |
0 0.05 | |
6 0)) | |
final-bright (min 96 | |
(max 10 | |
(gauss (+ mean-bright bright-adjust bright-adjust-2) 4))) | |
sat-adjust (max 0 (rescale ground-d | |
0 0.05 | |
3 0)) | |
alpha (min 1.0 (gauss 0.5 0.3)) | |
big? false | |
e-width (if big? | |
(max (w 0.0005) (gauss (w 0.0025) (w 0.003))) | |
(max (w 0.0001) (gauss (w 0.0004) (w 0.0002)))) | |
e-height (* e-width (gauss 1.0 0.2))] | |
(q/fill (gauss 25 2) | |
(max 0 (gauss sat-adjust 1)) | |
final-bright | |
alpha) | |
(if (> e-width (w 0.0004)) | |
(draw-dirty-dot x y (/ e-width 2.0) true 0) | |
(q/ellipse x y e-width e-height)))))) | |
(defn draw-right-metal-piece-shadow | |
[x-pos shadow-mask-graphics] | |
(q/with-graphics shadow-mask-graphics | |
(q/fill 0 0 75) | |
(q/no-stroke) | |
(q/begin-shape) | |
(q/vertex x-pos 0) | |
(q/vertex x-pos (h)) | |
(let [noise-offset (q/random 0 (h 100.0))] | |
(doseq [y (range (h) (h -0.02) (h -0.005))] | |
(let [n (q/noise (/ (+ y noise-offset) (h 0.025))) | |
x-offset (rescale n 0.0 1.0 (w -0.002) (w -0.0005))] | |
(q/vertex (+ x-pos x-offset) y))) | |
(q/end-shape :close)))) | |
(defn draw-right-metal-piece | |
[x-pos] | |
(q/no-stroke) | |
(doseq [y (range 0 (h) (h 0.005))] | |
(let [bright (cond | |
(< y (h 0.55)) | |
(min 99 (rescale y 0 (h 0.55) 105 93)) | |
(< y (h 0.87)) | |
(max 59 (rescale y (h 0.55) (h 0.87) 93 70)) | |
:else | |
(max 59 (rescale y (h 0.87) (h) 70 81))) | |
sat (cond | |
(< y (h 0.55)) | |
(rescale y 0 (h 0.55) 5 8) | |
(< y (h 0.87)) | |
(rescale y (h 0.55) (h 0.87) 8 7) | |
:else | |
(rescale y (h 0.87) (h) 7 3)) | |
highlight-bright (rescale y 0 (h) 99 80)] | |
; base | |
(q/fill 220 sat bright) | |
(q/rect x-pos y (w 0.004) (h 0.006)) | |
(when (between? y (h 0.15) (h 0.153)) | |
(q/fill 220 0 (- bright 12)) | |
(q/rect x-pos y (w 0.004) (h 0.0015))) | |
; rightmost highlight | |
(q/fill 220 2 highlight-bright) | |
(q/rect (+ x-pos (w 0.004)) y (w 0.0004) (h 0.007)) | |
; left mid | |
(q/fill 220 sat (- bright 8)) | |
(q/rect x-pos y (w 0.001) (h 0.007)) | |
(when (between? y (h 0.15) (h 0.15)) | |
(q/fill 220 0 (- bright 14)) | |
(q/rect x-pos (- y (h 0.001)) (w 0.001) (h 0.0015))) | |
; left weak highlight | |
(q/fill 220 2 (- highlight-bright 4)) | |
(q/rect x-pos y (w 0.0003) (h 0.007)) | |
; inner right highlight | |
(q/fill 220 2 highlight-bright) | |
(q/rect (+ x-pos (w 0.0008)) y (w 0.0005) (h 0.007))))) | |
(defn draw-left-metal-piece | |
[x-pos] | |
; left metal base | |
(q/fill 220 3 17) | |
(q/rect (- x-pos (w 0.004)) 0 (w 0.004) (h 1.01)) | |
(doseq [y (range 0 (h) (h 0.005))] | |
(let [hue (mod (rescale y 0 (h) 220 410) 360) | |
sat (max 2 (rescale y 0 (h) -2 19)) | |
bright (rescale y 0 (h) 17 23.5)] | |
(q/fill hue sat bright) | |
(q/rect (- x-pos (w 0.004)) y (w 0.004) (h 0.007)))) | |
(doseq [y (range 0 (h) (h 0.005))] | |
(let [bright (if (< y (h 0.65)) | |
(rescale y 0 (h 0.65) 90 75) | |
(max 57 (rescale y (h 0.65) (h) 75 53))) | |
highlight-bright (rescale y 0 (h) 97.5 75)] | |
; center | |
(q/fill 220 3 bright) | |
(q/rect (- x-pos (w 0.0007)) y (w 0.0007) (h 0.007)) | |
; inner right highlight | |
(q/fill 220 2 highlight-bright) | |
(q/rect (- x-pos (w 0.0002)) y (w 0.0005) (h 0.007))))) | |
(defn draw-vent | |
[] | |
(q/no-stroke) | |
; black shadow | |
(q/fill 0 0 2) | |
(q/rect 0 0 (w 0.07) (h 0.148)) | |
(let [the-overlay (q/create-graphics (w 0.07) (h 0.15)) | |
the-mask (q/create-graphics (w 0.07) (h 0.15))] | |
(q/with-graphics the-overlay | |
(set-color-mode)) | |
(q/with-graphics the-mask | |
(set-color-mode)) | |
(doseq [y (range (h -0.0073) (h 0.15) (h 0.0237))] | |
(q/fill 50 1 5) | |
(q/rect 0 y (w 0.0685) (h 0.011)) | |
; bottom reflection-based highlight | |
(q/fill 220 2 10) | |
(doseq [x (range 0 (w 0.0655) (w 0.002))] | |
(let [bright (max 7 (rescale x 0 (w 0.0735) 19 9))] | |
(q/fill 50 1 bright) | |
(q/rect x (+ y (h 0.008)) (w 0.003) (h 0.003)))) | |
(q/fill 220 2 10) | |
(doseq [x (range 0 (w 0.0655) (w 0.002))] | |
(let [bright (max 4 (rescale x 0 (w 0.0735) 14 4))] | |
(q/fill 50 1 bright) | |
(q/rect x (+ y (h 0.008)) (w 0.003) (h 0.001)))) | |
(q/fill 220 0 2) | |
(q/rect 0 (+ y (h 0.0047)) (w 0.0685) (h 0.001)) | |
; lower lit portion | |
(q/with-graphics the-mask | |
(q/background 0 0 0) | |
(q/no-stroke) | |
(let [points [[0 (+ y (h 0.006))] | |
[(w 0.033) (+ y (h 0.006))] | |
[(w 0.035) (+ y (h 0.006))] | |
[(w 0.0375) (+ y (h 0.008))] | |
[(w 0.0355) (+ y (h 0.008))] | |
[0 (+ y (h 0.008))]] | |
smoothed-points (chaikin-curve-retain-ends points 1 0.25)] | |
(q/fill 0 0 70) | |
(q/begin-shape) | |
(doseq [[x y] smoothed-points] | |
(q/vertex x y)) | |
(q/end-shape :close) | |
(q/fill 0 0 100) | |
(q/begin-shape) | |
(doseq [[x y] smoothed-points] | |
(q/vertex (- x (w 0.0008)) y)) | |
(q/end-shape :close))) | |
(q/with-graphics the-overlay | |
(let [mean-bright (rescale y 0 (h 0.14) 70 78)] | |
(q/background 50 9 mean-bright) | |
(q/no-stroke) | |
(doseq [x (range 0 (w 0.038) (w 0.0002)) | |
y (range (- y (h 0.01)) (+ y (h 0.01)) (w 0.0005))] | |
(let [n (q/noise (/ x (w 0.002)) (/ y (w 0.002))) | |
bright-adjust (rescale n 0.0 1.0 -11.0 11.0) | |
final-bright (+ mean-bright bright-adjust)] | |
(q/fill 50 7 (gauss final-bright 1)) | |
(q/rect x y (w 0.001) (w 0.001)))))) | |
(.mask the-overlay the-mask) | |
(q/image the-overlay 0 0) | |
; upper lit portion | |
(q/with-graphics the-mask | |
(q/background 0 0 0) | |
(q/no-stroke) | |
(let [points [[0 (+ y (h 0.0013))] | |
[(w 0.027) (+ y (h 0.0013))] | |
[(w 0.029) (+ y (h 0.0013))] | |
[(w 0.033) (+ y (h 0.0045))] | |
[(w 0.027) (+ y (h 0.0045))] | |
[0 (+ y (h 0.0045))]] | |
smoothed-points (chaikin-curve-retain-ends points 1 0.25)] | |
(q/fill 0 0 70) | |
(q/begin-shape) | |
(doseq [[x y] smoothed-points] | |
(q/vertex x y)) | |
(q/end-shape :close) | |
(q/fill 0 0 100) | |
(q/begin-shape) | |
(doseq [[x y] smoothed-points] | |
(q/vertex (- x (w 0.0008)) y)) | |
(q/end-shape :close))) | |
(q/with-graphics the-overlay | |
(let [mean-bright (rescale y 0 (h 0.14) 58 66)] | |
(q/background 50 8 mean-bright) | |
(q/no-stroke) | |
(doseq [x (range 0 (w 0.035) (w 0.0002)) | |
y (range (- y (h 0.01)) (+ y (h 0.01)) (w 0.0005))] | |
(let [n (q/noise (/ x (w 0.002)) (/ y (w 0.002))) | |
bright-adjust (rescale n 0.0 1.0 -17.0 17.0) | |
final-bright (+ mean-bright bright-adjust)] | |
(q/fill 50 6 (gauss final-bright 1)) | |
(q/rect x y (w 0.001) (w 0.001)))))) | |
(.mask the-overlay the-mask) | |
(q/image the-overlay 0 0))) | |
; lower wide border | |
(q/fill 220 8 52) | |
(q/rect 0 (h 0.143) (w 0.0685) (h 0.005)) | |
; highlight on lower wide border | |
(q/fill 220 8 67) | |
(q/rect 0 (h 0.143) (w 0.0685) (h 0.0006)) | |
; shadow on lower wide border | |
(q/fill 220 6 15) | |
(q/rect (w 0.0634) (h 0.143) (w 0.0051) (h 0.005)) | |
(q/fill 220 8 11) | |
(q/rect (w 0.0638) (h 0.143) (w 0.0047) (h 0.005)) | |
; right wide border | |
(q/fill 220 8 11) | |
(q/rect (w 0.066) 0 (w 0.0025) (h 0.143)) | |
; inner diagonal | |
(q/stroke 0 0 5) | |
(q/stroke-weight (w 0.0004)) | |
(q/line (w 0.066) (h 0.143) | |
(w 0.0685) (h 0.148)) | |
(q/no-stroke) | |
; center of right border | |
(q/fill 220 7 54) | |
(q/rect (w 0.0685) 0 (w 0.001) (h 0.15)) | |
; rightmost highlight | |
(q/fill 220 4 80) | |
(q/rect (w 0.0693) 0 (w 0.0007) (h 0.15)) | |
; center of bottom border | |
(q/fill 220 6 44) | |
(q/begin-shape) | |
(q/vertex 0 (h 0.148)) | |
(q/vertex (w 0.0685) (h 0.148)) | |
(q/vertex (w 0.0697) (+ (h 0.148) (w 0.0015))) | |
(q/vertex 0 (+ (h 0.148) (w 0.0015))) | |
(q/end-shape) | |
; highlight on bottom border | |
(q/fill 220 2 60) | |
(q/rect 0 (h 0.148) (w 0.0685) (w 0.0005)) | |
; lower shadow | |
(q/fill 0 0 0 0.75) | |
(q/begin-shape) | |
(q/vertex 0 (+ (h 0.148) (w 0.0015))) | |
(q/vertex (w 0.07) (+ (h 0.148) (w 0.0015))) | |
(doseq [x (range (w 0.07) (w -0.005) (w -0.0005))] | |
(let [n (q/noise (/ x (w 0.005))) | |
y-adjust (rescale n 0.0 1.0 (w -0.0001) (w 0.0007))] | |
(q/vertex x (+ (h 0.15) (w 0.0005) y-adjust)))) | |
(q/end-shape :close) | |
; diagonal joint | |
(q/stroke 0 0 5) | |
(q/stroke-weight (w 0.0004)) | |
(q/line (w 0.0685) (h 0.148) | |
(w 0.0696) (h 0.1505)) | |
(q/no-stroke)) | |
(defn sidewalk-noise | |
[x y] | |
(let [n (q/noise (/ x (w 0.01)) (/ y (w 0.01))) | |
y-adjust (rescale n 0.0 1.0 (h -0.0004) (h 0.0013))] | |
[x (+ y y-adjust)])) | |
(defn draw-sidewalk | |
[] | |
(q/no-stroke) | |
(let [left-y (h 0.984) | |
corner-x (w 0.105) | |
corner-y (h 0.99) | |
[_ adjusted-corner-y] (sidewalk-noise corner-x corner-y)] | |
(q/fill 40 7 70) | |
(q/begin-shape) | |
(doseq [t (range 0.0 1.01 0.02)] | |
(let [x (interpolate 0 corner-x t) | |
y (interpolate left-y corner-y t)] | |
(apply q/vertex (sidewalk-noise x y)))) | |
(q/vertex corner-x (h)) | |
(q/vertex 0 (h)) | |
(q/end-shape :close) | |
; texture on gray part | |
(doseq [t (range 0.0 0.78 0.01)] | |
(let [x0 (interpolate 0 corner-x t) | |
y0 (interpolate left-y corner-y t) | |
[x1 y1] (sidewalk-noise x0 y0) | |
[x2 y2] (angular-coords x1 y1 (pi 0.77) (w 0.03)) | |
t2 (min 1.0 (max 0.0 (q/random -0.3 1.3))) | |
start-x (interpolate x1 x2 t2) | |
start-y (interpolate y1 y2 t2) | |
t3 (min 1.0 (max 0.0 (q/random -0.3 1.3))) | |
end-x (interpolate x1 x2 t3) | |
end-y (interpolate y1 y2 t3)] | |
(q/stroke-weight (max (w 0.0001) (gauss (w 0.0003) (w 0.00015)))) | |
(q/stroke (gauss 40 1) (gauss 7 1) (gauss 71 4)) | |
(q/line start-x start-y end-x end-y) | |
(q/no-stroke) | |
(dotimes [_ 30] | |
(let [t (q/random 0.0 1.0) | |
x (interpolate x1 x2 t) | |
y (interpolate y1 y2 t) | |
diam (gauss (w 0.0005) (w 0.0002))] | |
(q/fill (gauss 40 2) (gauss 7 2) (gauss 71 5)) | |
(q/ellipse x y diam diam))))) | |
; yellow top | |
(let [mask (q/create-graphics corner-x (h 0.03)) | |
overlay (q/create-graphics corner-x (h 0.03))] | |
(q/with-graphics mask | |
(set-color-mode) | |
(q/background 0 0 0) | |
(q/fill 0 0 100) | |
(q/no-stroke) | |
(q/begin-shape) | |
(doseq [t (range 0.78 1.01 0.02)] | |
(let [x0 (interpolate 0 corner-x t) | |
y0 (interpolate left-y corner-y t) | |
[x1 y1] (sidewalk-noise x0 y0)] | |
(q/vertex x1 (- y1 (h 0.97))))) | |
(q/vertex (- corner-x (w 0.0050)) (h 0.03)) | |
(q/vertex (w 0.075) (h 0.03)) | |
(q/end-shape)) | |
(q/with-graphics overlay | |
(set-color-mode) | |
(q/background 40 70 86) | |
(q/no-stroke) | |
(doseq [x (range 0 corner-x (w 0.0005)) | |
y (range 0 (h 0.03) (w 0.0005))] | |
(let [e-width (max (w 0.0002) (gauss (w 0.0008) (w 0.0003))) | |
e-height (* e-width (gauss 1.0 0.05)) | |
n (q/noise (/ x (w 0.01)) (/ y (w 0.05))) | |
bright-adjust (rescale n 0.0 1.0 -15.0 15.0)] | |
(q/fill 40 70 (gauss (+ 86 bright-adjust) 2) 0.8) | |
(q/ellipse x y e-width e-height)))) | |
(.mask overlay mask) | |
(q/image overlay 0 (h 0.97))) | |
(q/stroke 30 18 30) | |
(q/stroke-weight (w 0.0005)) | |
(q/begin-shape) | |
(q/vertex (+ corner-x (w 0.0002)) adjusted-corner-y) | |
(q/vertex (+ corner-x (w 0.0010)) (interpolate (h) adjusted-corner-y 0.3)) | |
(q/vertex (+ corner-x (w 0.0011)) (h)) | |
(q/end-shape) | |
; yellow highlight | |
(q/no-stroke) | |
(q/fill 40 60 98) | |
(q/begin-shape) | |
(q/vertex corner-x adjusted-corner-y) | |
(q/vertex (+ corner-x (w 0.0008)) (interpolate (h) adjusted-corner-y 0.3)) | |
(q/vertex (+ corner-x (w 0.0013)) (h)) | |
(q/vertex (- corner-x (w 0.0050)) (h)) | |
(q/vertex (- corner-x (w 0.0035)) (interpolate (h) adjusted-corner-y 0.5)) | |
(q/end-shape) | |
; brown part | |
(let [mask (q/create-graphics corner-x (h 0.05)) | |
overlay (q/create-graphics corner-x (h 0.05))] | |
(q/with-graphics mask | |
(set-color-mode) | |
(q/background 0 0 0) | |
(q/no-stroke) | |
(q/fill 0 0 100) | |
(q/begin-shape) | |
(doseq [t (range 0 1.01 0.01)] | |
(let [x1 (interpolate 0 corner-x t) | |
y1 (interpolate left-y corner-y t) | |
n (q/noise (/ (- x1 (w 5.0)) (w 0.002))) | |
mag-max (rescale t 0 1.0 (w 0.004) (w 0.0008)) | |
mag (rescale n 0.0 1.0 0.0 mag-max)] | |
(q/vertex x1 (- y1 mag (h 0.95))))) | |
(doseq [t (range 1.0 -0.01 -0.02)] | |
(let [x0 (interpolate 0 corner-x t) | |
y0 (interpolate left-y corner-y t) | |
[x1 y1] (sidewalk-noise x0 y0)] | |
(q/vertex x1 (+ y1 (h 0.0005) (h -0.95))))) | |
(q/end-shape)) | |
(q/with-graphics overlay | |
(set-color-mode) | |
(q/background 30 38 35) | |
(q/no-stroke) | |
(dotimes [_ 3000] | |
(let [t (q/random 0.0 1.0) | |
x1 (interpolate 0 corner-x t) | |
y1 (interpolate left-y corner-y t) | |
y-offset (gauss (w 0.002) (w 0.002)) | |
e-width (max (w 0.0001) (gauss (w 0.0005) (w 0.0005)))] | |
(q/fill (gauss 30 8) (max 5 (gauss 38 8)) (gauss 35 8)) | |
(draw-dirty-dot x1 (+ y1 y-offset (h -0.95)) | |
(* e-width 0.5) | |
true 0)))) | |
(.mask overlay mask) | |
(q/image overlay 0 (h 0.95))))) | |
(defn draw-right-reflected-highlight | |
[near-x-right overlay-graphics mask-graphics] | |
(q/with-graphics mask-graphics | |
(q/background 0 0 0) | |
(q/no-stroke) | |
(doseq [x-offset (range 0 (w 0.05) (w 0.001))] | |
(let [bright (/ 104 (Math/pow (+ 1 (/ x-offset (w 0.005))) 1.2))] | |
(doseq [y (range 0 (h 1.02) (h 0.01))] | |
(let [final-bright (min 100 (max 0 (rescale y 0 (h) (* bright 1.1) (* bright -0.2))))] | |
(q/fill 0 0 final-bright) | |
(q/rect (+ near-x-right x-offset) y | |
(w 0.0012) (h 0.011))))))) | |
(q/with-graphics overlay-graphics | |
(q/background 0 0 100)) | |
(.mask overlay-graphics mask-graphics) | |
(q/image overlay-graphics 0 0 (w) (h))) | |
(defn add-splatter | |
[] | |
(q/no-stroke) | |
(let [noise-offset-1 (q/random 0 (w 1000.0)) | |
noise-offset-2 (q/random 0 (w 1000.0))] | |
(when (not= detail-level :low) | |
(dotimes [_ 600000] | |
(let [x (q/random 0 (w)) | |
draw-odds (q/noise noise-offset-2 (/ (+ x (w 100.0)) (w 0.07)))] | |
(when (odds draw-odds) | |
(let [n1 (q/noise (/ (+ x noise-offset-1) (w 0.12))) | |
y-variance (rescale n1 0.0 1.0 (h 0.01) (h 0.13)) | |
y-variance (weighted-choice | |
(* y-variance 15.0) 0.1 | |
(* y-variance 7.0) 0.1 | |
(* y-variance 3.0) 0.1 | |
y-variance 0.7) | |
y (- (h) (abs-gauss 0 y-variance)) | |
diam (max (w 0.0001) (gauss (w 0.00027) (w 0.00020))) | |
diam (if (odds 0.007) | |
(if (odds 0.5) | |
(* diam 2) | |
(* diam 3.4)) | |
diam) | |
alpha (if (odds 0.02) | |
(min 1.0 (gauss 0.8 0.1)) | |
(max 0.03 (min 1.0 (gauss 0.05 0.10)))) | |
hue (if (odds 0.01) | |
(q/random 0 250) | |
(gauss 35 8)) | |
sat (max 0 (gauss 20 10)) | |
bright (weighted-choice | |
(max 8 (gauss 25 12)) 0.08 | |
(gauss 50 12) 0.05 | |
(gauss 60 5) 0.87) | |
num-reps (weighted-choice | |
1 0.89 | |
2 0.05 | |
3 0.03 | |
4 0.02 | |
5 0.01)] | |
(dotimes [_ num-reps] | |
(q/fill (gauss hue 2) (gauss sat 3) (gauss bright 3) (gauss alpha 0.05)) | |
(let [diam (gauss diam (* diam 0.25))] | |
(if (> diam (w 0.00035)) | |
(draw-dirty-dot (gauss x diam) (gauss y diam) (/ diam 2.0) true (pi 0.7)) | |
(q/ellipse x y diam diam))))))))))) | |
(defn actual-draw | |
[] | |
(q/background 0 0 48) | |
(let [spacing (int (w 0.005)) | |
left-x (w -0.1) | |
right-x (w 1.1) | |
top-y (h -0.1) | |
bot-y (h 1.1) | |
row-width (int (Math/ceil (/ (- right-x left-x) spacing))) | |
default-theta 0 | |
flow-points (get-flow-points default-theta spacing left-x right-x top-y bot-y) | |
get-theta (fn [x y] | |
(let [x-offset (int (/ (- x left-x) spacing)) | |
y-offset (int (/ (- y top-y) spacing)) | |
index (+ x-offset (* row-width y-offset)) | |
[_ _ theta] (if (between? index 0 (dec (count flow-points))) | |
(nth flow-points index) | |
[0 0 default-theta])] | |
theta)) | |
get-offset (fn [x y] | |
(let [theta (get-theta x y) | |
mag (w 0.03)] | |
(angular-coords 0 0 theta mag))) | |
target-x-step (/ (w 1.0) 25.3333) | |
target-y-step (/ (h 1.0) 51.0) | |
grout-ratio 0.04 | |
rear-brick-width (/ target-x-step (+ 1.0 grout-ratio)) | |
rear-vertical-grout-spacing (* rear-brick-width grout-ratio) | |
horizontal-grout-ratio 0.195 | |
; rear-brick-height (* rear-brick-width 0.295) | |
rear-brick-height (/ target-y-step (+ 1.0 horizontal-grout-ratio)) | |
rear-horizontal-grout-spacing (* rear-brick-height horizontal-grout-ratio) | |
rear-x-step (+ rear-brick-width rear-vertical-grout-spacing) | |
rear-y-step (+ rear-brick-height rear-horizontal-grout-spacing) | |
near-brick-width (* rear-brick-height 1.01) | |
near-brick-height (* rear-brick-width 1.01) | |
near-horizontal-grout-spacing (* rear-horizontal-grout-spacing 0.7) | |
near-vertical-grout-spacing (* rear-vertical-grout-spacing 1.01) | |
near-x-step (+ near-brick-width near-vertical-grout-spacing) | |
near-y-step (+ near-brick-height near-horizontal-grout-spacing) | |
near-x-width (- (* near-x-step 10.0) (* rear-vertical-grout-spacing 1.01)) | |
near-x-left (- (w 0.5) (* near-x-width 0.5)) | |
near-x-right (+ (w 0.5) (* near-x-width 0.5)) | |
near-overlay-graphics (q/create-graphics (+ near-x-step (w 0.01)) (+ near-y-step (w 0.01))) | |
near-mask-graphics (q/create-graphics (+ near-x-step (w 0.01)) (+ near-y-step (w 0.01))) | |
shadow-mask-graphics (q/create-graphics (w) (h)) | |
shadow-overlay-graphics (q/create-graphics (w) (h)) | |
; near-brick-mask-graphics (q/create-graphics near-x-width (h)) | |
near-brick-overlay-graphics (q/create-graphics near-x-width (h))] | |
(color-grout (w)) | |
(q/with-graphics shadow-mask-graphics | |
(set-color-mode) | |
(q/background 0 0 0) | |
(q/no-stroke) | |
(q/fill 0 0 75)) | |
(q/with-graphics shadow-overlay-graphics | |
(set-color-mode) | |
(q/background 0 0 0) | |
(doseq [y (range 0 (h 1.01) (h 0.01))] | |
(let [ground-d (Math/pow (/ (- (h) y) (h)) 2) | |
bright-adjust (max 0 (rescale ground-d | |
0 0.25 | |
7 0)) | |
sat-adjust (max 0 (rescale ground-d | |
0 0.25 | |
100 0))] | |
(q/no-stroke) | |
(q/fill 20 sat-adjust bright-adjust) | |
(q/rect 0 y (w) (h 0.011))))) | |
(q/with-graphics near-overlay-graphics | |
(set-color-mode)) | |
(q/with-graphics near-mask-graphics | |
(set-color-mode) | |
(q/no-stroke) | |
(q/fill 0 0 100)) | |
; (q/with-graphics shadow-mask-graphics | |
; (q/fill 0 0 75) | |
; (q/rect (- near-x-left (w 0.0189)) 0 (w 0.0186) (h 1.01))) | |
(q/with-graphics shadow-mask-graphics | |
(doseq [[x-offset bright] [[(w -0.00025) 50] | |
[(w 0.00025) 75]]] | |
(q/fill 0 0 bright) | |
(q/begin-shape) | |
(doseq [y (range 0 (h) (h 0.0005))] | |
(let [n (q/noise (/ y (w 0.02))) | |
x-noise-offset (rescale n 0 1.0 (w -0.001) (w 0.001))] | |
(q/vertex (+ near-x-left (w -0.0189) x-offset x-noise-offset) y))) | |
(q/vertex (+ near-x-left (w 0.0186)) (h)) | |
(q/vertex (+ near-x-left (w 0.0186)) 0) | |
(q/end-shape :close))) | |
; rear bricks | |
; 25 and 1/3rd bricks wide | |
; 51 bricks tall | |
(doseq [[i y] (enumerate (range (h -0.025) (h) rear-y-step))] | |
(println "doing row" i) | |
(let [x-start (if (and (even? i) (not= i 52)) | |
(* rear-x-step -2.9) | |
(* rear-x-step -2.4)) | |
brick-width (if (= i 52) | |
(* rear-brick-width 0.3067) | |
rear-brick-width) | |
x-step (+ brick-width rear-vertical-grout-spacing) | |
rear-overlay-graphics (q/create-graphics (+ x-step (w 0.01)) (+ rear-y-step (w 0.01))) | |
rear-mask-graphics (q/create-graphics (+ x-step (w 0.01)) (+ rear-y-step (w 0.01)))] | |
(q/with-graphics rear-overlay-graphics | |
(set-color-mode)) | |
(q/with-graphics rear-mask-graphics | |
(set-color-mode) | |
(q/no-stroke) | |
(q/fill 0 0 100)) | |
(doseq [x (reverse (range x-start (w 1.05) x-step))] | |
(draw-brick | |
x y | |
brick-width rear-brick-height | |
rear-horizontal-grout-spacing rear-vertical-grout-spacing | |
rear-overlay-graphics rear-mask-graphics | |
shadow-mask-graphics | |
get-offset)))) | |
; middle/near/vertical bricks | |
(q/fill 0 0 49) | |
(q/no-stroke) | |
(q/rect near-x-left 0 near-x-width (h)) | |
(q/with-graphics near-brick-overlay-graphics | |
(set-color-mode) | |
(color-grout near-x-left)) | |
(q/image near-brick-overlay-graphics near-x-left 0) | |
(q/with-graphics shadow-mask-graphics | |
(q/fill 0 0 0) | |
(q/rect near-x-left 0 near-x-width (h))) | |
(doseq [y (range (h -0.012) (h) near-y-step)] | |
(let [y-shift (gauss 0 (h 0.00038))] | |
(doseq [x (reverse (range near-x-left (- near-x-right (w 0.01)) near-x-step))] | |
(draw-brick-vertical | |
x (+ y y-shift) | |
near-brick-width near-brick-height | |
near-horizontal-grout-spacing near-vertical-grout-spacing | |
near-overlay-graphics near-mask-graphics shadow-mask-graphics)))) | |
(add-splatter) | |
(q/with-graphics shadow-mask-graphics | |
(q/fill 0 0 75) | |
(q/rect (- near-x-left (w 0.0178)) 0 (w 0.017) (h))) | |
(draw-right-metal-piece-shadow near-x-right shadow-mask-graphics) | |
(.mask shadow-overlay-graphics shadow-mask-graphics) | |
(q/image shadow-overlay-graphics 0 0 (w) (h)) | |
(draw-right-reflected-highlight near-x-right shadow-overlay-graphics shadow-mask-graphics) | |
(draw-right-metal-piece near-x-right) | |
(draw-left-metal-piece near-x-left) | |
(draw-sidewalk) | |
(draw-vent))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment