/** letters that resolve to a swarm by guru
click on the letters ... */ import geomerative.*; Boid[] b; RFont font; RGroup grp; int mode = 0; int row =0; void setup() { size(400,400); RG.init(this); font = new RFont( "VeraBd.ttf", 75, RFont.CENTER); grp = font.toGroup("Boids"); grp.translate( 0, -10 ); RCommand.setSegmentLength(3); RCommand.setSegmentator(RCommand.UNIFORMLENGTH); grp = grp.toPolygonGroup(); initP(); } void draw() { translate( width/2, height/2 + 75); background(255); for ( int i=0; i < b.length; i ++ ) { if ( mode == 1 ) { b[i].update(); } b[i].draw(); } for ( int i=0; i < b.length; i ++ ) { if ( mode == 1 ) { if (b[i].y < row ) { b[i].fixed = false; } } } row++; } void mousePressed() { if ( mode == 0 ) { mode = 1; row = -75; } else { mode = 0; initP(); } } void initP() { RPoint[] pnts = grp.getPoints(); b = new Boid[pnts.length]; for ( int i=0; i < b.length; i ++ ) { b[i] = new Boid( pnts[i].x , pnts[i].y, random( -2, 2 ), random( -2, 2 ), b ); } } public class Boid { float r1 = 40; float r2 = 80; float r3 = 160; boolean fixed; float x,y; float vx, vy; Boid[] others; public Boid( float x, float y, float vx, float vy, Boid[] others ) { this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.others = others; fixed = true; } void boo() { vx = random( -25, 25 ); vy = random( -25, 25 ); } public void update() { if (fixed) return; sep(); align(); coh(); float l = sqrt( sq( vx ) + sq ( vy )); if (l > 4 ) { vx = 0.9 * vx; vy = 0.9 * vy; } x += vx; y += vy; if (x > width/2 - 15 ) { vx -= 2; } if (x < -width/2 + 15 ) { vx += 2; } if (y > height/2 -60 ) {vy -= 2; } if (y < -height/2 -90) { vy += 2; } } public void sep() { int count = 0; float sx = 0; float sy = 0; for ( int i = 0; i < others.length; i ++ ) { float d = sqrt( sq( x - others[i].x ) + sq( y - others[i].y )); if (d < r1 && this != others[i] ) { count++; sx += others[i].x; sy += others[i].y; } } if ( count > 0 ){ sx = x - sx / count; sy = y - sy / count; float l = sqrt( sq( sx ) + sq ( sy )); sx = 1.2 * sx / l; sy = 1.2 * sy / l; } vx += sx; vy += sy; } public void align() { int count = 0; float dx = 0; float dy = 0; for ( int i = 0; i < others.length; i ++ ) { float d = sqrt( sq( x - others[i].x ) + sq( y - others[i].y )); if (d < r2 && this != others[i] ) { count++; dx += others[i].vx; dy += others[i].vy; } } if ( count > 0 ){ dx = dx / count; dy = dy / count; float l = sqrt( sq( dx ) + sq ( dy )); dx = dx / l; dy = dy / l; } vx += dx; vy += dy; } public void coh() { int count = 0; float sx = 0; float sy = 0; for ( int i = 0; i < others.length; i ++ ) { float d = sqrt( sq( x - others[i].x ) + sq( y - others[i].y )); if (d < r3 && d > r1 && this != others[i] ) { count++; sx += others[i].x; sy += others[i].y; } } if ( count > 0 ){ sx = x - sx / count; sy = y - sy / count; float l = sqrt( sq( sx ) + sq ( sy )); sx = sx / l; sy = sy / l; } vx -= sx; vy -= sy; } public void draw() { fill(255); stroke( 127 ); pushMatrix(); translate( x, y ); rotate( atan( vy/vx ) + ( vx < 0 ? PI : 0 )); beginShape(); vertex( -2, -2 ); vertex( -2, 2 ); vertex( 2, 2 ); vertex( 2, -2 ); endShape(CLOSE); popMatrix(); } }