1 ! Copyright (C) 2008 Eduardo Cavazos.
2 ! Copyright (C) 2011 Anton Gorenko.
3 ! See http://factorcode.org/license.txt for BSD license.
4 USING: accessors arrays combinators.short-circuit kernel math
5 math.vectors random sequences ;
23 { 0.0 0.0 } [ v+ ] reduce ; inline
26 [ vsum ] [ length ] bi v/n ; inline
28 : in-radius? ( self other radius -- ? )
29 [ [ pos>> ] bi@ distance ] dip <= ; inline
31 : angle-between ( u v -- angle )
32 [ normalize ] bi@ vdot ; inline
34 : relative-position ( self other -- v )
35 swap [ pos>> ] bi@ v- ; inline
37 :: relative-angle ( self other -- angle )
38 self other relative-position
39 self vel>> angle-between ; inline
41 : in-view? ( self other angle-cos -- ? )
42 [ relative-angle ] dip >= ; inline
44 :: within-neighborhood? ( self other behavior -- ? )
47 [ behavior radius>> in-radius? ]
48 [ behavior angle-cos>> in-view? ]
51 :: neighbors ( boid boids behavior -- neighbors )
52 boid boids [ behavior within-neighborhood? ] with filter ;
54 GENERIC: force ( neighbors boid behavior -- force )
56 :: (force) ( boid boids behavior -- force )
57 boid boids behavior neighbors
58 [ { 0.0 0.0 } ] [ boid behavior force ] if-empty ;
60 : wrap-pos ( pos -- pos )
61 WIDTH HEIGHT 2array [ [ + ] keep mod ] 2map ;
63 :: simulate ( boids behaviors dt -- boids )
66 [ [ (force) ] keep weight>> v*n ] 2with map vsum :> a
68 boid vel>> a dt v*n v+ normalize :> vel
69 boid pos>> vel dt v*n v+ wrap-pos :> pos
74 : random-boids ( count -- boids )
76 WIDTH HEIGHT [ random ] bi@ 2array
77 2 [ 0 1 normal-random-float ] replicate
81 TUPLE: cohesion < behavior ;
82 TUPLE: alignment < behavior ;
83 TUPLE: separation < behavior ;
85 C: <cohesion> cohesion
86 C: <alignment> alignment
87 C: <separation> separation
89 M: cohesion force ( neighbors boid behavior -- force )
90 drop [ [ pos>> ] map vavg ] [ pos>> ] bi* v- normalize ;
92 M: alignment force ( neighbors boid behavior -- force )
93 2drop [ vel>> ] map vsum normalize ;
95 M:: separation force ( neighbors boid behavior -- force )
96 behavior radius>> :> r
98 [ pos>> v- [ normalize ] [ r v/n ] bi v- ] with map vsum ;