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 my journal, published March 16, 2016, in Berlin.