Ronin experiment 17 - boids
I have written several implementation of craig rainolds boids in languages like processing or openframeworks, so I had to give it a try in ronin as well. Especially since the original implementation was done in common lisp :-)
(def particles { :p () })
(def r1 40)
(def r2 80)
(def r3 160)
(defn init () (
(set particles "p" (map (range 1 30) (lambda (a)
{
:id a
:x (random 0 600)
:y (random 0 600)
:vx (random -1 1)
:vy (random -1 1)
}
))))
)
(defn len (a b) (sqrt (add (sq (sub a:x b:x)) (sq (sub a:y b:y)))))
(defn sep (p) (
(def s { :x 0 :y 0 :c 0 })
(each particles:p (lambda (o) (
(if (or (eq o:id p:id) (gt (len p o) r1)) () (
(set s "x" (add s:x o:x))
(set s "y" (add s:y o:y))
(set s "c" (add s:c 1))
))
)))
(if (gt s:c 0) (
(set s "x" (sub p:x (div s:x s:c)))
(set s "y" (sub p:y (div s:y s:c)))
(def l (sqrt (add (sq s:x) (sq s:y))))
(set s "x" (mul 1.2 (div s:x l)))
(set s "y" (mul 1.2 (div s:y l)))
))
(set p "vx" (add p:vx s:x))
(set p "vy" (add p:vy s:y))
))
(defn align (p) (
(def s { :x 0 :y 0 :c 0 })
(each particles:p (lambda (o) (
(if (or (eq o:id p:id) (gt (len p o) r2)) () (
(set s "x" (add s:x o:vx))
(set s "y" (add s:y o:vy))
(set s "c" (add s:c 1))
))
)))
(if (gt s:c 0) (
(set s "x" (div s:x s:c))
(set s "y" (div s:y s:c))
(def l (sqrt (add (sq s:x) (sq s:y))))
(set s "x" (div s:x l))
(set s "y" (div s:y l))
))
(set p "vx" (add p:vx s:x))
(set p "vy" (add p:vy s:y))
))
(defn coh (p) (
(def s { :x 0 :y 0 :c 0 })
(each particles:p (lambda (o) (
(if (or (eq o:id p:id) (or (lt (len p o) r1) (gt (len p o) r3))) () (
(set s "x" (add s:x o:x))
(set s "y" (add s:y o:y))
(set s "c" (add s:c 1))
))
)))
(if (gt s:c 0) (
(set s "x" (sub p:x (div s:x s:c)))
(set s "y" (sub p:y (div s:y s:c)))
(def l (sqrt (add (sq s:x) (sq s:y))))
(set s "x" (div s:x l))
(set s "y" (div s:y l))
))
(set p "vx" (sub p:vx s:x))
(set p "vy" (sub p:vy s:y))
))
(defn update () (
(each particles:p (lambda (p) (
(sep p)
(align p)
(coh p)
(set p "x" (add p:x p:vx))
(set p "y" (add p:y p:vy))
(def l (sqrt (add (sq p:vx) (sq p:vy))))
(if (gt l 4) (
(set p "vx" (mul p:vx 0.9))
(set p "vy" (mul p:vy 0.9))
))
(if (lt p:x 40) (
(set p "vx" (add p:vx 2))
))
(if (lt p:y 40) (
(set p "vy" (add p:vy 2))
))
(if (gt p:x 560) (
(set p "vx" (sub p:vx 2))
))
(if (gt p:y 560) (
(set p "vy" (sub p:vy 2))
))
)))
))
(clear)
(resize 600 600)
(init)
(defn draw (p) (
(stroke
(fill
(circle p:x p:y 10)
(rgba 200 200 200 0.8)
)
(rgba 50 50 50 1 ) 2
)
))
(on "animate" '(
(fill (frame) (rgba 0 0 0 0.2))
(update)
(each particles:p (lambda (p) (
(draw p)
)))
))
See also:
Ronin experiment 15 - particles
Ronin experiment 21 - morphing lissajous states
ronin experiment 20 - transform flower
ronin experiment 19 - Sonic Pi visualizer
Ronin experiment 18 - Rainbow
Ronin experiment 21 - morphing lissajous states
ronin experiment 20 - transform flower
ronin experiment 19 - Sonic Pi visualizer
Ronin experiment 18 - Rainbow