(ns aphorisms.fourty-one (:require [thi.ng.geom.core :as g] [thi.ng.geom.vector :as v] [quil.core :as q] [quil.middleware :as qm] [thi.ng.geom.rect :as r] [aphorisms.utils.middleware :refer [screenshottable]] [thi.ng.geom.line :as l] [thi.ng.math.core :as m] [thi.ng.geom.utils.intersect :as isec])) ;; More practice to get a feeling for the `thi.ng` API again ;; Resizing cells in the grid, generating random lines and playing with intersections (def height 500 #_(int (* width (Math/sqrt 2)))) (def width #_500 (int (* height (Math/sqrt 2)))) (def padding (* height 0.1)) (def canvas (r/rect width height)) (defn center-in "Centers `r2` in or around `r1`." [r1 r2] (g/translate (assoc r2 :p (:p r1)) (v/vec2 (* 0.5 (- (g/width r1) (g/width r2))) (* 0.5 (- (g/height r1) (g/height r2)))))) (def bounds (center-in canvas (r/rect (- width (* 2 padding)) (- height (* 2 padding))))) (defn as-grid [rect cell-size] (let [n-x (int (/ (g/width rect) cell-size)) n-y (int (/ (g/height rect) cell-size)) t (v/vec2 (* (mod (g/width rect) n-x) 0.5) (* (mod (g/height rect) n-x) 0.5))] (for [x (range n-x) y (range n-y)] (-> (r/rect (* x cell-size) (* y cell-size) cell-size) (g/translate (:p rect)) (g/translate t ))))) (def grid (map #(g/scale-size % 0.92) (as-grid bounds 50))) (defn line-inside [rect] (l/line2 (g/random-point-inside rect) (g/random-point-inside rect))) ;; below is the rendering logic (defn setup [] (q/frame-rate 30) (q/color-mode :hsb 360 100 100) (q/rect-mode :center) (q/ellipse-mode :center) (q/background 350) {:lines (repeatedly 5 #(line-inside bounds))}) (defn update-state [state] state) (defn mouse-pressed [state _] (assoc state :lines (repeatedly 20 #(line-inside bounds)))) (let [l (l/line2 50 50 200 210)] (g/intersect-line l (first (g/edges (first grid))))) (defn draw-state [state] (q/translate -0.5 -0.5) (q/background 180 0 98) (q/stroke-weight 0.5) (q/no-fill) (q/stroke 320 100 70) (doseq [line (:lines state) :let [[a b] (g/vertices line)]] (q/line a b)) (doseq [cell grid [a b] (g/edges cell)] (q/line a b)) (q/no-stroke) (q/fill 320 100 70) (doseq [cell grid line (:lines state) isecs (->> (map #(g/intersect-line line %) (g/edges cell)) (keep #(when (= (:type %) :intersect) (:p %)))) :let [[i1 i2] isecs]] (q/ellipse i1 i2 5 5))) #_:clj-kondo/ignore (q/defsketch fourty-one :title "Fourty One" :size [width height] :settings (fn [] (q/smooth 2) (q/pixel-density (q/display-density))) :setup setup :update #'update-state :mouse-pressed #'mouse-pressed :draw #'draw-state :features [:keep-on-top :no-bind-output] :middleware [qm/pause-on-error qm/fun-mode (screenshottable)])