[WIP] Use an intermediate "branches" data model to draw l-system trees

This commit is contained in:
Jeremy Dormitzer 2022-02-20 15:29:18 -05:00
parent e1e83b42da
commit 59876ea2d8

View File

@ -6,6 +6,59 @@
(defn degrees->radians [deg]
(* deg (/ js/Math.PI 180)))
;; The tree branch object
;; A branch has a coordinate, a list of segments and a map of child branches
;; A segment has an angle and a length
;; The child branch map's keys are the segment index at which the
;; child branch originates, and the values are the child branch itself
(defn l-system-tree
[{:keys [segment-length initial-angle initial-x initial-y l-system]}]
(let [make-tree
(fn make-tree [segment-length x y angle symbols branch idx]
(let [[symbol & rest-symbols] symbols]
(condp = symbol
nil branch
"F" (let [new-x (+ x (* segment-length
(js/Math.cos (degrees->radians angle))))
new-y (+ y (* (- segment-length)
(js/Math.sin (degrees->radians angle))))
branch (assoc branch
:segments
(conj (:segments branch)
{:length segment-length
:angle angle}))]
(recur segment-length new-x new-y angle rest-symbols branch (inc idx)))
"+" (recur segment-length x y (+ angle 25) rest-symbols branch idx)
"-" (recur segment-length x y (- angle 25) rest-symbols branch idx)
"*" (recur segment-length x y (+ angle 20) rest-symbols branch idx)
"/" (recur segment-length x y (- angle 20) rest-symbols branch idx)
">" (recur segment-length x y (+ angle 15) rest-symbols branch idx)
"<" (recur segment-length x y (- angle 15) rest-symbols branch idx)
"[" (let [new-branch (make-tree segment-length
x
y
angle
rest-symbols
{:x x
:y y
:segments []
:children {}}
0)
branch (assoc-in branch [:children idx] new-branch)]
(recur segment-length x y angle rest-symbols branch idx))
"]" branch ;; stop processing current branch and pop to parent call
(recur segment-length x y angle rest-symbols branch idx))))]
(make-tree segment-length
initial-x
initial-y
initial-angle
(:state l-system)
{:x initial-x
:y initial-y
:segments []
:children {}}
0)))
(defn l-system-lines
[{:keys [segment-length initial-angle initial-x initial-y l-system]}]
(vec
@ -65,6 +118,11 @@
"F" -> "FF")
:random-fn (partial q/random 1)})
((apply comp (repeat 6 l-system/step))))
tree (l-system-tree {:initial-angle (- 90 25)
:segment-length 6
:initial-x (* (q/width) 0.1)
:initial-y (* (q/height) 0.95)
:l-system l-system})
lines (l-system-lines {:initial-angle (- 90 25)
:segment-length 6
:initial-x (* (q/width) 0.1)