Skip to content

Instantly share code, notes, and snippets.

@mthomure
Created February 15, 2016 19:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mthomure/a51ed9ada64ccbd6b5bd to your computer and use it in GitHub Desktop.
Save mthomure/a51ed9ada64ccbd6b5bd to your computer and use it in GitHub Desktop.
drive processing (simple drawing) with leap motion and midi controllers
(ns hello-quil.noisy-spirals
(:require [quil.core :as q]
[hello-quil.noisy-spirals-dynamic :as d]
[clojure.core.async :as a]
[overtone.midi :as midi]
[mojion.leap :as leap]))
(q/defsketch gen-art-14
:title "100 Noisy Spirals"
:size [d/SIZE d/SIZE]
:setup d/setup
:draw d/draw)
(defn -main [midi-dev-name]
(let [leap-ch (a/chan (a/sliding-buffer 10))]
(leap/connect #(a/offer! leap-ch %))
(a/go-loop []
(d/handle-leap (a/<! leap-ch))
(recur)))
(let [midi-dev (midi/midi-in midi-dev-name)
midi-ch (a/chan (a/sliding-buffer 10))]
(midi/midi-handle-events dev #(a/offer! midi-ch %))
(a/go-loop []
(d/handle-midi (a/<! midi-ch))
(recur)))
(ns hello-quil.noisy-spirals-dynamic
(:require [quil.core :refer :all]
[quil.helpers.drawing :refer [line-join-points]]
[quil.helpers.seqs :refer [range-incl steps]]
[quil.helpers.calc :refer [mul-add]]
[clojure.pprint :refer [pprint]]))
(def SIZE 800)
(defonce pstate
(atom {:red {:mean 10 :range 10}
:green {:mean 25 :range 25}
:blue {:mean 35 :range 35}
:alpha 80
:running true
:radius 100
:thickness 0.1
:center {:x 250 :y 250}
:save-path nil}))
(defn setup []
(background 255)
(smooth)
(frame-rate 30))
(defn draw []
(let [{:keys [red green blue alpha save-path center radius thickness
running]} @pstate]
(when running
(stroke-weight thickness)
(let [
radius 100
{cent-x :x cent-y :y} center
start-angle (rand 360)
end-angle (+ 1440 (rand 1440))
angle-step (+ 5 (rand 3))
rad-noise (steps (rand 10) 0.05)
rad-noise (map #(* 200 (noise %)) rad-noise)
rads (map radians (range-incl start-angle end-angle angle-step))
radii (steps 10 0.5)
radii (map (fn [rad noise] (+ rad noise -100)) radii rad-noise)
xs (map (fn [rad radius] (mul-add (cos rad) radius cent-x)) rads radii)
ys (map (fn [rad radius] (mul-add (sin rad) radius cent-y)) rads radii)
line-args (line-join-points xs ys)
clr (fn [{:keys [mean range]}] (+ mean (rand range)))]
(stroke (clr red) (clr green) (clr blue) alpha)
(dorun (map #(apply line %) line-args))))
(when (some? save-path)
(do
;; save at most once
(swap! pstate assoc-in [:save-path] nil)
(print (format "saving to: %s" save-path))
(save save-path)))))
(defn pause []
(let [new-state (swap! pstate update-in [:running] not)]
(pprint (str "running: " (:running new-state)))))
(defn save-drawing
([]
(save-drawing "drawing.png"))
([path]
(pprint "save")
(swap! pstate assoc-in [:save-path] path)))
(defn clamp [x xmin xmax]
(min xmax (max xmin x)))
;; calibration data
(def LEAP-RANGE {:x [-100 100]
:y [30 270]
:z [-100 100]})
(defn handle-leap [m]
(when-let [[x y z] (get-in m [:hands 0 :palmPosition])]
(let [->clr #(-> % (+ 128) (clamp 0 255) int)
->colors (fn [st]
(-> st
(assoc-in [:red :mean] (->clr x (:x LEAP-RANGE)))
(assoc-in [:green :mean] (->clr y (:y LEAP-RANGE)))
(assoc-in [:blue :mean] (->clr z (:z LEAP-RANGE)))))
->loc (fn [v [vmin vmax]]
(-> v (- vmin) (/ (- vmax vmin)) (clamp 0 1) (* SIZE)))
->thick (fn [v [vmin vmax]]
(let [vnorm (-> v (- vmin) (/ (- vmax vmin)) (clamp 0 1))]
(->> vnorm (- 1) (* 2))))
st (swap! pstate
(fn [st]
(-> st
(assoc-in [:center :x] (->loc x (:x LEAP-RANGE)))
(assoc-in [:center :y] (->loc z (:z LEAP-RANGE)))
(assoc-in [:thickness] (->thick y (:y LEAP-RANGE))))))]
(pprint [x y z])
#_(pprint (select-keys (swap! pstate ->colors) [:red :green :blue]))
(pprint (select-keys st [:center :thickness])))))
(defn handle-midi [{:keys [command note velocity] :as m}]
(let [set-color #(swap! pstate assoc-in [% :mean]
(-> velocity (* 2) (clamp 0 255)))
set-position #(swap! pstate assoc-in [:center %]
(-> velocity (/ 128) double (* SIZE) int))
set-thickness #(swap! pstate assoc-in [:thickness]
(-> velocity (/ 128) double))]
(case [command note]
[:control-change 1] (set-color :red)
[:control-change 2] (set-color :green)
[:control-change 3] (set-color :blue)
[:control-change 5] (set-position :x)
[:control-change 6] (set-position :y)
[:control-change 7] (set-thickness)
[:note-on 48] (pause)
[:note-on 49] (save-drawing)
nil)))
(defproject hello-quil "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.7.0"]
[quil "2.3.0"]
[overtone/midi-clj "0.5.0"]
[org.clojure/core.async "0.2.374"]
[mojion "0.1.0-SNAPSHOT"]])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment