Finish thirty-four

"Emergence", pau's christmas present
This commit is contained in:
arne 2022-12-31 12:20:18 +01:00
commit 2b8ca91ae4
13 changed files with 91 additions and 38 deletions

View file

@ -0,0 +1 @@
[[{:shape #thi.ng.geom.types.Circle2{:p [1250.0 0.0], :r 200.0}}]]

View file

@ -0,0 +1 @@
[({:shape #thi.ng.geom.types.Circle2{:p [1169.2141779985973 124.35578668857836], :r 100.0}, :direction [-0.5575868896660603 0.8301185821751786]}) ({:shape #thi.ng.geom.types.Circle2{:p [1461.5281637402827 -74.57103604070437], :r 100.0}, :direction [0.9722871336022564 -0.23378992671094295]})]

View file

@ -0,0 +1 @@
[({:shape #thi.ng.geom.types.Circle2{:p [1082.8670584761762 -145.84166316106112], :r 96.98885345458984}, :direction [-0.6994623197526844 -0.7146694783228074]}) ({:shape #thi.ng.geom.types.Circle2{:p [1397.9053390456197 -9.560041299767816], :r 88.95150756835938}, :direction [0.9995071663742341 -0.031391469646211895]}) ({:shape #thi.ng.geom.types.Circle2{:p [1392.1154406814385 262.9955610966998], :r 92.90243530273438}, :direction [0.4367768501324125 0.899569887884431]}) ({:shape #thi.ng.geom.types.Circle2{:p [1243.6272455078717 -276.1374644111995], :r 64.9386978149414}, :direction [-0.023067785725857996 -0.9997339032271066]}) ({:shape #thi.ng.geom.types.Circle2{:p [1177.0357554199327 163.0054812721723], :r 71.03009033203125}, :direction [-0.410184728106374 0.9120024609771072]})]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,27 +1,40 @@
(ns aphorisms.thirty-four (ns aphorisms.thirty-four
(:require [quil.core :as q] (:require [quil.core :as q]
[quil.applet :as qa]
[quil.middleware :as qm] [quil.middleware :as qm]
[thi.ng.geom.rect :as r] [thi.ng.geom.rect :as r]
[thi.ng.geom.core :as g] [thi.ng.geom.core :as g]
[thi.ng.geom.circle :as c] [thi.ng.geom.circle :as c]
[thi.ng.geom.spatialtree :as st] [thi.ng.geom.spatialtree :as st]
[thi.ng.math.core :as m])) [thi.ng.math.core :as m]
[thi.ng.geom.vector :as v]
[heyarne.line-us.connection :as line-us]
[heyarne.line-us.gcode :as gcode]
[heyarne.line-us.helpers :as lh]))
;; attempt to implement the hyphae algorithm described in ;; attempt to implement the hyphae algorithm described in
;; https://inconvergent.net/generative/hyphae/ ;; https://inconvergent.net/generative/hyphae/
(def bounds (r/rect 750 500)) (def bounds (r/rect [800 -900]
(def canvas (g/scale bounds 0.92)) [1700 900])) ;; line-us drawing area: [[700;1800], [-1000;1000]]
(defn pad [rect p]
(let [p (v/vec2 p)]
(-> (update rect :p #(g/translate % p))
(update :size #(g/translate % (m/* p -2))))))
(def canvas (pad bounds [32 32]))
;; parameters to influence how the end result looks ;; parameters to influence how the end result looks
(def start-size 7.0) (def start-size 15.0)
(def min-size 4.0) (def min-size 10.0)
(def shrink 0.8) ;; factor by which size decreases at each step (def shrink 0.8) ;; factor by which size decreases at each step
(def spaciousness 2.5) ;; size of neighbor-check for each node (def spaciousness 2.5) ;; size of neighbor-check for each node
(def max-path-length 30) ;; how long are the strings of nodes? (def max-path-length 100) ;; how long are the strings of nodes?
(def num-paths 45) ;; how many strings should be generated max? (def num-paths 100) ;; how many strings should be generated max?
;; all nodes look like this: {:shape circ, :direction vec2} ;; all nodes look like this: {:shape circ, :direction vec2}
@ -29,20 +42,19 @@
(empty? (st/select-with-shape quadtree (g/scale-size (:shape node) spaciousness)))) (empty? (st/select-with-shape quadtree (g/scale-size (:shape node) spaciousness))))
(defn nice-place? [quadtree node] (defn nice-place? [quadtree node]
(and (g/contains-point? (g/scale-size bounds 0.8) (-> node :shape :p)) (and (g/contains-point? canvas (-> node :shape :p))
(empty-neighborhood? quadtree node))) (empty-neighborhood? quadtree node)))
(defn wobble [v] (defn wobble [v]
(g/rotate v (m/radians (m/random -20 20)))) (g/rotate v (m/radians (m/random -10 10))))
(defn pick-start [quadtree] (defn pick-start [quadtree]
(->> (repeatedly 10 (fn [] (->> (repeatedly 10 (fn []
(let [pt (g/random-point-inside (g/scale-size bounds 0.5)) (let [pt (g/random-point-inside #_(c/circle (g/centroid canvas) 100) (g/scale-size canvas 0.8))
dir (wobble (m/normalize (m/- (g/centroid bounds) pt)))] dir (wobble (g/rotate (m/normalize (m/- (g/centroid canvas) pt)) (* Math/PI 0.4 (Math/random))))]
{:shape (c/circle pt start-size) {:shape (c/circle pt start-size)
:direction dir}))) :direction dir})))
(filter #(nice-place? quadtree (update % :shape (fn [circ] (filter #(nice-place? quadtree %))
(g/scale-size circ 1.5)))))
(first))) (first)))
(defn next-node [quadtree path] (defn next-node [quadtree path]
@ -63,11 +75,6 @@
(* 0.99 (+ (-> node :shape :r) (-> other :shape :r))))) path)))) ;; floating point errors? (* 0.99 (+ (-> node :shape :r) (-> other :shape :r))))) path)))) ;; floating point errors?
(first)))) (first))))
(comment
(make-path (st/quadtree bounds))
)
;; let's generate different paths of hyphae, each at most `max-path-length` nodes long ;; let's generate different paths of hyphae, each at most `max-path-length` nodes long
(defn make-path [quadtree] (defn make-path [quadtree]
@ -83,6 +90,14 @@
(ffirst) (ffirst)
(take-last max-path-length)))) (take-last max-path-length))))
(comment
(make-path (st/quadtree bounds))
)
;; single circle
#_(def paths [[{:shape (c/circle (g/centroid bounds) 200)}]])
;; generated scene
(def paths (def paths
(let [qt (st/quadtree bounds)] (let [qt (st/quadtree bounds)]
(for [_ (range num-paths) (for [_ (range num-paths)
@ -91,6 +106,32 @@
(reduce #(g/add-point %1 (-> %2 :shape :p) %2) qt path) ;; add-point is mutable (reduce #(g/add-point %1 (-> %2 :shape :p) %2) qt path) ;; add-point is mutable
path)))) path))))
(comment
;; save interesting scenes
(spit "exports/20221229-scene-1-single-circle.edn" (vec paths))
(spit "exports/20221229-scene-2-scattered-circles.edn" (vec paths))
(spit "exports/20221229-scene-3-scatter-more.edn" (vec paths))
(spit "exports/20221229-scene-4-feeling-and-finding-larger.edn" (vec paths))
(spit "exports/20221229-scene-5-emergence-larger.edn" (vec paths))
;; load particular scene from disk
(def paths (read-string (slurp "exports/20221229-scene-5-emergence-larger.edn")))
;; plot currently visible scene
(with-open [line-us (line-us/connect "line-us.fritz.box" 1337)]
(line-us/send-command! line-us "G94 S2")
(doseq [#_#_coords (into [] cat (gcode/scene->gcode-seq [bounds])) ;; for calibration
coords (->>
(into [] (comp cat
(map :shape)
(map #(update % :p v/vec2))) ;; this is required because of a bug in the reader
paths)
(gcode/scene->gcode-seq)
(into [] cat)
#_(lh/rescale (r/rect [700 -1000] [1800 1000])))]
(line-us/send-movement! line-us coords)))
)
(defn setup [] (defn setup []
(q/ellipse-mode :center) (q/ellipse-mode :center)
(q/rect-mode :corners) (q/rect-mode :corners)
@ -98,23 +139,23 @@
{}) {})
(defn draw-state [_] (defn draw-state [_]
(q/scale 0.5)
(q/with-translation (m/* (:p bounds) -1)
(q/background 255) (q/background 255)
(q/no-fill) (q/no-fill)
(doseq [path paths (doseq [path paths
{{[x y] :p r :r} :shape} path] {{[x y] :p r :r} :shape} path]
(q/ellipse x y (* 2 r) (* 2 r))) (q/ellipse x y (* 2 r) (* 2 r)))
#_(qd/draw-scene! scene)) #_(qd/draw-scene! scene)))
(when-not (resolve 'thirty-four) ;; #_:clj-kondo/ignore
#_:clj-kondo/ignore #_(q/defsketch thirty-four
(q/defsketch thirty-four
:title "Thirty-Four" :title "Thirty-Four"
:size (:size bounds) :size (g/scale (:size bounds) 0.5)
:settings #(q/pixel-density (q/display-density)) :settings #(q/pixel-density (q/display-density))
:features [:keep-on-top] :features [:keep-on-top]
:setup setup :setup setup
:update identity :update identity
:draw draw-state :draw draw-state
:middleware [qm/pause-on-error #_(screenshottable) qm/fun-mode]) :middleware [qm/pause-on-error #_(screenshottable) qm/fun-mode])
)