/**
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();
}
}