Diffusion-limited aggregation with particles

Trying to reinstate “fluxus friday” where I reserve some time for livecoding or fluxus hacking at the end of the week. First up, a new way of making fuzzy blobs in fluxus – particle aggregation. I like the analogue feel to it – reminds me of the voxels from last year. I also found this for syntax highlighting lisp for blog posts.

; a blurry particle aggregation example
(clear)
(hint-depth-sort)
(blend-mode 'src-alpha 'one)
(define p (build-particles 500))
(define r 1)

; setup the particle primitive
(with-primitive p
(pdata-add "a" "f") ; 1 if we have attached to another particle
(pdata-add "vel" "v") ; velocity array
(pdata-map! (lambda (a) 0) "a") ; init to zero
(pdata-set! "a" 0 1)
(pdata-map! (lambda (c) 0.1) "c") ; init the colour
(pdata-map!
(lambda (p)
(vmul (hsrndvec) r)) ; space out in a hollow sphere
"p")
(pdata-map!
(lambda (vel p)
(vector 0.02 0 0)) ; init velocities
"vel" "p")
(pdata-set! "p" 0 (vector 0 0 0)))

; check particle n against all others and return #t if we
; are close enouth to another to aggregate
(define (collide? n)
(let ((np (pdata-ref "p" n)))
(pdata-index-fold
(lambda (i p a r)
(if (and (not r) (not (zero? a)) (not (eq? i n)) (< (vdist p np) 0.05))
#t r))
#f "p" "a")))

(every-frame
(with-primitive p
(pdata-map!
(lambda (p vel a)
(if (zero? a) ; if we're not attached
(if (> (vmag p) r) ; and we are outside the sphere
(vmul (hsrndvec) r) ; reset position
(vadd p vel)) ; move with velocity
p))
"p" "vel" "a")
(pdata-index-map! ; check all particles and set a if they
(lambda (i a) ; have attached to any others
(if (and (zero? a) (collide? i)) 1 a))
"a")))