Skip to content

Instantly share code, notes, and snippets.

@nbeloglazov
Created February 21, 2014 18:04
Show Gist options
  • Select an option

  • Save nbeloglazov/9139657 to your computer and use it in GitHub Desktop.

Select an option

Save nbeloglazov/9139657 to your computer and use it in GitHub Desktop.
(ns mouse-example
(:require [quil.core :as q]))
(def w 1000)
(def h 1000)
(def acc 500)
(let [id (atom 0)]
(defn next-id []
(swap! id inc)))
(defn dist->force [d]
(if (zero? d)
1000
(/ d)))
(defn force [[b-x b-y] [p-x p-y]]
(let [d (q/dist b-x b-y p-x p-y)
f (* acc (dist->force d))
angle (q/atan2 (- b-y p-y) (- b-x p-x))]
[(* f (q/cos angle))
(* f (q/sin angle))]))
(defn wall-force [[b-x b-y]]
(map * [(- (dist->force b-x)
(dist->force (- w b-x)))
(- (dist->force b-y)
(dist->force (- h b-y)))]
[acc acc]))
(defn force->color [force]
(let [f (Math/hypot (first force) (last force))
max-force 10
f (q/constrain f 0 max-force)]
(processing.core.PApplet/map f 0 max-force 240 360)))
(defn log [n]
(println n)
n)
(def diffs #{3 5 7 11})
(defn apply-forces [body pushers]
(let [force (->> (filter #(diffs (mod (q/abs (- (:id body) (:id %))) 15))
pushers)
(map :pos)
(map #(force (:pos body) %))
(reduce #(map + %1 %2) [0 0])
(map + (wall-force (:pos body))))]
(-> body
(update-in [:pos] #(map + force %))
(assoc-in [:color] (force->color force)))))
(defn setup []
(q/smooth)
(q/no-stroke)
(q/frame-rate 30)
(q/color-mode :hsb 360 100 100)
(q/set-state! :mouse-position (atom [0 0])
:bodies (atom [{:pos [100.0 100.0]}])))
(defn update-bodies [bodies mouse]
(let [pushers (conj bodies {:pos mouse
:id -1})]
(map #(apply-forces % pushers) bodies)))
(defn update []
(swap! (q/state :bodies) update-bodies @(q/state :mouse-position)))
(defn draw []
(update)
(q/background-float 125)
(q/color-mode :hsb 360 100 100)
(q/stroke-weight 1)
; (stroke-float 10)
; (println (random-gaussian))
(q/stroke 0 0 0)
(q/fill 120 100 100)
(let [[x y] @(q/state :mouse-position)]
(q/ellipse x y 20 20))
(doseq [{:keys [pos color id]} @(q/state :bodies)]
(q/fill color 100 100)
(q/ellipse (first pos) (last pos) 50 50)
(q/fill 0 0 0)
(apply q/text (str id) pos)))
(defn mouse-moved []
(let [x (q/mouse-x) y (q/mouse-y)]
(reset! (q/state :mouse-position) [x y])))
(defn mouse-clicked []
(case (q/mouse-button)
:left (swap! (q/state :bodies) conj {:pos [(rand-int w)
(rand-int h)]
:id (next-id)})
:right (swap! (q/state :bodies) empty)
:nothing))
(q/defsketch mouse-example
:title "Mouse example."
:size [w h]
:setup setup
:draw draw
:mouse-moved mouse-moved
:mouse-clicked mouse-clicked)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment