;; ;; behave2.al: multiple beasts, repulse plus center attract ;; (define *sim-length* 90) (define *render?* #t) (define *repulse-force* .005) (define *attract-force* .1) (define *num-beasts* 20) (define *beasts* '()) (define *speed* .1) (define (randR low high) (+ low (* (rand) (- high low)))) (define (get-value p key) (list-ref (assq key p) 1)) (define (set-value p key val) (set-cdr! (assq key p) (list val))) (define (update-beast beast) (let ((force 0) (pos (get-value beast 'p)) (change (vec3 0 0 0)) ) ; calc repulse force from other beasts (for i 0 (- *num-beasts* 1) 1 ; don't compare beast to itself (if (not (eq? beast (list-ref *beasts* i))) (let* ((other-beast (list-ref *beasts* i)) (other-pos (get-value other-beast 'p)) (d (distance pos other-pos)) (dir (normalize (- pos other-pos))) (f (* *repulse-force* (/ 1 (sqr d)) dir)) ) (set! force (+ force f)) )) ) ; calc attract force to center (set! force (+ force (* *attract-force* (sqr (norm pos)) (normalize (- pos))))) ; calc beast move (set! change (* (normalize force) (get-value beast 'speed))) (set-value beast 'v change) ; set new beast position (set-value beast 'p (+ pos change)) )) (define (update-beasts) (map update-beast *beasts*)) (define (draw-beast beast) (separator (translate (get-value beast 'p)) (uscale .1) (color 1 0 0) (sphere))) (define (draw-beasts) (map draw-beast *beasts*)) (define (add-beast p) (set! *beasts* (cons p *beasts*))) (define (make-one-beast) (list (list 'p (vec3 0 0 0)) (list 'v (vec3 0 0 0)) (list 'speed 1) )) (define (create-beast) (let ( (b (make-one-beast)) ) (set-value b 'p (vec3 (randR -1 1) (randR -1 1) 0)) (set-value b 'v (vec3 (randR -1 1) (randR -1 1) 0)) (set-value b 'speed *speed*) (add-beast b) )) (define (create-beasts) (for i 1 *num-beasts* 1 (create-beast))) (define (sim) (begin (create-beasts) (for i 1 *sim-length* 1 (begin (world (camera "main" "orthographic" 'from (vec3 0 0 1.25)) (draw-beasts) ) (if *render?* (render 'style "vector" 'format '(320 242) 'display-type "sgif" 'display-name (string-append "Frames/f" (number->string i) ".rgb") )) (update-beasts) )))) (sim) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;