Gumball Machine

Here’s an example of Karsten Schmidt‘s th.ing libraries to produce the simplest possible physics simulation.
There’s a live version compiled down to JS here.
The source code is relatively succinct:
(ns gumball-machine.core (:require [thi.ng.color.core :as col] [thi.ng.math.core :as m] [thi.ng.geom.core :as g] [thi.ng.geom.core.vector :refer [vec3]] [thi.ng.geom.physics.core :as ph] [thi.ng.geom.sphere :refer [sphere]] [quil.core :as q :include-macros true])) (def particles (repeatedly 20 #(ph/particle (vec3 (m/random -50 50) (m/random -50 50) (m/random -50 50)) 1))) (def engine (ph/physics {:particles particles :drag 0.05 :constraints {:w (ph/shape-constraint-inside (g/center (sphere 200)))} :behaviors {:g (ph/gravity (vec3 0 0.5 0))}})) (defn setup [] (q/smooth) (q/frame-rate 55) (q/color-mode :hsb) (q/no-stroke)) (defn draw [] ;; tick the world clock, recalculate particle positions (ph/timestep engine 1) ;; if all the particles have come to rest... (when (every? #(< (second (ph/velocity %)) 0.08) particles) ;; ... then apply a randomized force to them all (doseq [p particles] (ph/add-force p (vec3 (m/random -10 10) -10 (m/random -10 10))))) ;; set up bg + lighting conditions (q/background 18) (q/ambient-light 0 0 80) (q/directional-light 0 0 150 0 0 -1) (q/light-specular 0 0 200) (q/specular 0 0 70) (q/shininess 0.5) ;; draw the particles (q/with-translation [(/ (q/width) 2) (/ (q/height) 2) 100] (doseq [[i p] (map-indexed vector particles)] (let [[x y z] (ph/position p)] (q/fill (* i 12) 255 255) (q/with-translation [x y z] (q/sphere 6)))))) (q/defsketch gumball-machine :host "gumball-machine" :size [600 600] :renderer :p3d :setup setup :draw draw)
Other than a few Quil/Processing-specific bits related to 3D lighting, it’s almost as short as a natural description of the desired behavior.
§
This entry is part of Jack Rusher’s archive, originally published March 16th, 2016, in Berlin.