Last active
August 29, 2015 13:57
-
-
Save quephird/9651977 to your computer and use it in GitHub Desktop.
This was a procedural version of drawing I made using ArtRage for the iPad and inspired by lichens: http://quephird.deviantart.com/art/lichens-434718646. This code makes me retch, but it's functional and I need to mull things over a bit before I return to it.
This file contains hidden or 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
(ns procedural-lichens | |
(:use quil.core)) | |
(def screen-w 2880) | |
(def screen-h 1800) | |
(def lichens (atom [])) | |
(defn intersects? [[x1 y1 r1] [x2 y2 r2]] | |
"Determines if the two circles passed in intersect" | |
(let [dx (- x2 x1) | |
dy (- y2 y1) | |
distance-squared (+ (* dx dx) (* dy dy)) | |
sum-of-radii-squared (* (+ r1 r2) (+ r1 r2))] | |
(<= distance-squared sum-of-radii-squared))) | |
(defn intersects-any? [test-circle existing-circles] | |
"Determines if the test circle intersects with any of the existing circles" | |
(some true? (map #(intersects? test-circle %) existing-circles))) | |
(defn random-circle [[min-x max-x min-y max-y min-r max-r] existing-circles] | |
"Returns a random representation of a circle that does not intersect | |
with the set of circles passed in. The parameters of the resultant circle | |
are further restricted to the min and max values for x, y, and r." | |
(let [x (+ min-x (random (- max-x min-x))) | |
y (+ min-y (random (- max-y min-y))) | |
r (+ min-r (random (- max-r min-r)))] | |
(if (intersects-any? [x y r] existing-circles) | |
(recur [min-x max-x min-y max-y min-r max-r] existing-circles) | |
[x y r]))) | |
(defn random-color [seed-c variance] | |
"Returns a color that is a slight, random deviation from the seeded color" | |
(let [dc (repeatedly 3 (fn [] (- (* variance 0.5) (random variance))))] | |
(map + seed-c dc))) | |
(defn apothecia [max-r cup-c] | |
"Renders the set of spore cups for the center of a particular lichen" | |
(apply fill cup-c) | |
(no-stroke) | |
; TODO: | |
; | |
; Need better distribution of cups | |
(doseq [_ (range 20)] | |
(let [x (random (- max-r) max-r) | |
y (random (- max-r) max-r) | |
w (random (* max-r 0.2) (* max-r 0.4)) | |
l (* w (random 1 1.2)) | |
φ (random 180)] | |
(push-matrix) | |
(rotate (radians φ)) | |
(ellipse x y w l) | |
(pop-matrix)))) | |
(defn- lichen [outer-r outer-lobes outer-c] | |
"Renders a lichen, randomizing each of the lobes of each layer" | |
(let [sw (/ (* PI outer-r) outer-lobes) | |
multipliers [1 0.85 0.7] | |
rs (map #(* % outer-r) multipliers) | |
lobess (map #(* % outer-lobes) multipliers) | |
cs (map (fn [m] (map (fn [c] (* m c)) outer-c)) multipliers) | |
layers (map vector rs lobess cs) | |
apothecia-r (* outer-r 0.6) | |
apothecia-c (map #(* % 0.4) outer-c)] | |
(stroke-weight sw) | |
; Render each of the three layers | |
(doseq [[r lobes c] layers] | |
(apply stroke c) | |
(let [dθ (/ 360 lobes)] | |
(doseq [_ (range lobes)] | |
(let [left-dx (rand-int 20) | |
right-dx (rand-int 20) | |
dy (rand-int 20)] | |
(bezier 0 0 0 0 0 (+ r dy) (- left-dx) (+ r dy)) | |
(bezier 0 0 0 0 0 (+ r dy) right-dx (+ r dy)) | |
(rotate (radians dθ)))))) | |
(apothecia apothecia-r apothecia-c))) | |
(defn all-lichens [] | |
(doseq [each_lichen (range 32)] | |
(let [[x y r] (random-circle [0 screen-w 0 screen-h 100 200] @lichens) | |
lobes (+ 20 (random 5)) | |
c (random-color [255 127 0] 50)] | |
(push-matrix) | |
(translate x y) | |
(lichen r lobes c) | |
(pop-matrix) | |
(swap! lichens conj [x y r])))) | |
(defn rock-surface [] | |
; Base color | |
(background (+ 20 (random 50))) | |
(push-matrix) | |
; Base skew angle | |
(rotate (radians (random 45))) | |
(doseq [x (repeatedly 25 (fn [] (random screen-w)))] | |
; Vary the thickness of each stroke | |
(stroke-weight (+ 100 (random 200))) | |
; Vary the shade of grey | |
(stroke (+ 50 (random 50))) | |
; Rotate each stroke a little bit from the baseline angle | |
(push-matrix) | |
(rotate (radians (random 10))) | |
(line x (- screen-h) x screen-h) | |
(pop-matrix)) | |
(pop-matrix)) | |
(defn setup [] | |
(smooth) | |
(background 0) | |
(no-loop)) | |
(defn draw [] | |
; TODO: | |
; | |
; Need to introduce clumping; randomly choose starting number 2 to 4 and clump around them | |
(rock-surface) | |
(all-lichens)) | |
(sketch | |
:title "procedural lichens" | |
:setup setup | |
:draw draw | |
:renderer :java2d | |
:size [screen-w screen-h]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment