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
(texture (load-texture "splat.png"))
(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
        (lambda (p)
            (vmul (hsrndvec) r)) ; space out in a hollow sphere
        (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)))
            (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")))

    (with-primitive p
            (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" "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))

Leave a Reply

Your email address will not be published. Required fields are marked *