Skip to content

Instantly share code, notes, and snippets.

@jackrusher
Created January 18, 2016 10:57
Show Gist options
  • Save jackrusher/42a07abd72cb658f3157 to your computer and use it in GitHub Desktop.
Save jackrusher/42a07abd72cb658f3157 to your computer and use it in GitHub Desktop.
A quick 3D L-system implementation using Toxi's https://github.com/thi-ng libraries.
(defn grow [pos rot points len]
(let [[x y z] (last rot) ;; :( no M33 and no (g/rotate-xyz _ (vec3 x y z))
corners (map #(-> % (g/rotate-x x) (g/rotate-y y) (g/rotate-z z) (g/+ (last pos)))
[(vec3 0 0 0) (vec3 -1 0 0) (vec3 0 -1 0) (vec3 0 1 0)
(vec3 -1 0 len) (vec3 0 -1 len) (vec3 0 1 len) (vec3 0 0 len)])]
[(conj (pop pos) (last corners))
rot
(conj points (map gu/tessellate-3 (g/faces (apply cub/cuboid corners))))]))
(defn build-lsystem [l-system angle len]
(->> (reduce
(fn [[pos rot points] op]
(case op
\F (grow pos rot points (len))
\- [pos (conj (pop rot) (g/+ (last rot) (vec3 (- (angle)) 0 0))) points]
\+ [pos (conj (pop rot) (g/+ (last rot) (vec3 (angle) 0 0))) points]
\% [pos (conj (pop rot) (g/+ (last rot) (vec3 0 (- (angle)) 0))) points]
\& [pos (conj (pop rot) (g/+ (last rot) (vec3 0 (angle) 0))) points]
\> [pos (conj (pop rot) (g/+ (last rot) (vec3 0 0 (angle)))) points]
\< [pos (conj (pop rot) (g/+ (last rot) (vec3 0 0 (- (angle))))) points]
\| [pos (conj (pop rot) (g/+ (last rot) (vec3 (- (m/radians 180)) 0 0))) points]
\[ [(conj pos (last pos)) (conj rot (last rot)) points]
\] [(pop pos) (pop rot) points]
[pos rot points])) ;; no-op
[[(v/vec3 0 0 0)] [(v/vec3 0 0 0)] []]
l-system)
last
flatten))
(defn expand-l-system [rules curr-state depth]
(if (zero? depth)
curr-state
(mapcat #(expand-l-system rules (rules % [%]) (dec depth)) curr-state)))
(defn koch-like []
(build-lsystem (expand-l-system {\F "FF-F-F&F-F-F+F"} "F" 4)
#(m/radians 90)
#(+ (m/random -1.5 3.5) 12)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment