multiple species

pr002

import processing.opengl.*;
import processing.dxf.*;
boolean record = false;

mFlo mflo;
Targets[] targets;
Drops[] drops;
Beach beach;

float angle;
float angleZ;
//float scala=5.0;
float scala=3.0;
float tr=0.75;
int numD=55000;
int currD=0;
int numT=10;
int currT=0;
Vector3D goal1=new Vector3D(20,-20,-10); //first target

//float[][]gcds={{1.0,0.1,0.1,0.9,0.1,3,3},{1.0,0.1,0.1,0.9,0.1,3,3},{1.0,0.1,0.1,0.9,0.1,3,3},{1.0,0.1,0.1,0.9,0.1,3,3},{1.0,0.1,0.1,0.9,0.1,3,3},{1.0,0.1,0.1,0.9,0.1,3,3}};
float[][]gcds={{0.5,0.1,0.1,0.5,0.1,3,5},{0.5,0.1,0.1,0.5,0.1,3,5},{0.5,0.1,0.1,0.5,0.1,3,5},{0.5,0.1,0.1,0.5,0.1,3,5},{0.5,0.1,0.1,0.5,0.1,3,5},{0.5,0.1,0.1,0.5,0.1,3,5}};
//float[][]gcds={{0.1,0.1,0.9,0.9,0.1,7,7},{0.1,0.1,0.9,0.9,0.1,7,7},{0.1,0.1,0.9,0.9,0.1,7,7},{0.1,0.1,0.9,0.9,0.1,7,7},{0.1,0.1,0.9,0.9,0.1,7,7},{0.1,0.1,0.9,0.9,0.1,7,7}};
//float[][]gcds={{0.3,0.9,0.1,0.5,0.5,7,5},{0.3,0.9,0.1,0.5,0.5,7,5},{0.3,0.9,0.1,0.5,0.5,7,5},{0.3,0.9,0.1,0.5,0.5,7,5},{0.3,0.9,0.1,0.5,0.5,7,5},{0.3,0.9,0.1,0.5,0.5,7,5}};
//float[][]gcds={{0.1,0.9,0.9,0.9,0.9,15,3},{0.1,0.9,0.9,0.9,0.9,15,3},{0.1,0.9,0.9,0.9,0.1,15,3},{0.1,0.9,0.9,0.9,0.1,15,3},{0.1,0.9,0.9,0.9,0.1,15,3},{0.1,0.9,0.9,0.9,0.1,15,3}};
//float[][]gcds={{0.1,0.9,0.9,0.9,0.9,15,3},{0.3,0.9,0.1,0.5,0.5,3,5},{0.1,0.1,0.9,0.9,0.1,13,13},{0.5,0.1,0.1,0.5,0.1,3,5},{1.0,0.1,0.1,0.9,0.1,3,3},{0.1,0.9,0.9,0.9,0.1,15,3}};

void setup(){
//size(3307,2339,OPENGL);
size(1280,800,OPENGL);
smooth();
mflo=new mFlo();
drops=new Drops[numD];
for (int i=0;i<numD;i++){
drops[i]=new Drops();
}

targets= new Targets[numT];
for(int i=0; i<numT; i++){
targets[i]=new Targets();
}

beach=new Beach();
beach.makeB();
beach.makeW();

for (int i = 0; i <4; i++) {
mflo.addMonkk(new Monkk(new Vector3D(-50,beach.giveY(-50,-50),-50),1.5f,0.05f, goal1, gcds[0],color(random(10,100),130,50)));
}

for (int i = 0; i <4; i++) {
mflo.addMonkk(new Monkk(new Vector3D(-80,beach.giveY(-80,-40),-40),1.5f,0.05f, goal1, gcds[1],color(random(10,100),110,10)));
}

for (int i = 0; i <4; i++) {
mflo.addMonkk(new Monkk(new Vector3D(-20,beach.giveY(-20,-80),-80),1.5f,0.05f, goal1, gcds[2],color(random(10,100),110,0)));
}

for (int i = 0; i <4; i++) {
mflo.addMonkk(new Monkk(new Vector3D(-40,beach.giveY(-40,-60),-60),1.5f,0.05f, goal1, gcds[3],color(random(10,100),210,0)));
}

for (int i = 0; i <4; i++) {
mflo.addMonkk(new Monkk(new Vector3D(-40,beach.giveY(-40,-100),-100),1.5f,0.05f, goal1, gcds[4],color(random(10,100),121,5)));
}

for (int i = 0; i <4; i++) {
mflo.addMonkk(new Monkk(new Vector3D(-100,beach.giveY(-100,-10),-10),1.5f,0.05f, goal1, gcds[5],color(random(10,100),110,50)));
}

}

void draw(){
if (record == true) {
beginRaw(DXF, “output.dxf”); // Start recording to the file
}
//saveFrame(“ani/prev-####.png”);
if(keyPressed&&key==’o’||key==’O’){
saveFrame(“screens/screen-####.png”);
}
background(255);

if(keyPressed&&key==’q’||key==’Q’){
scala+=0.1;
}
if(keyPressed&&key==’a’||key==’A’){
scala-=0.1;
}
if(keyPressed&&key==’w’||key==’W’){
tr+=0.004;
}
if(keyPressed&&key==’s’||key==’S’){
tr-=0.004;
}
if(keyPressed&&key==’e’||key==’E’){
angleZ += 0.02;
}
if(keyPressed&&key==’d’||key==’D’){
angleZ -= 0.02;
}
if(mousePressed&&mouseButton==LEFT){
angle -= 0.02;
}
if(mousePressed&&mouseButton==RIGHT){
angle += 0.02;
}

translate(width/2, height*tr, 0);
scale(scala);
rotateY(angle);
rotateX(angleZ);

for(int i=0;i<currD;i++){
drops[i].display();
}

if(keyPressed&&key==’1′){
mflo.run(1);
}
//lights();
beach.displayB();
beach.displayW();
mflo.display();
for(int i=0; i<numT; i++){
targets[i].display();
}

if (record == true) {
endRaw();
record = false; // Stop recording to the file
}

}

void keyPressed() {
if (key == ‘R’ || key == ‘r’) { // Press R to save the file
record = true;
}
if (key == ‘T’ || key == ‘t’) { // Press R to save the file
if (currT==numT){
currT=0;
}
targets[currT].add(random(-100,100),random(-100,0),random(-100,100),random(10,100));
mflo.changeTarget(new Vector3D(targets[currT].x,targets[currT].y,targets[currT].z));
currT++;
}
}

class Beach{
int det=100;
float[][][]coordB =new float[det][det][3];
float[][][]coordW =new float[det][det][3];

void makeB(){
for (int i=0;i<det;i++){
for (int j=0;j<det;j++){
coordB[i][j][0]=-2*det+i*4;
coordB[i][j][1]=100-pow(fuzzyDist(dist(i,0,j,0,0,0),1,70)*8,2)-pow(fuzzyDist(dist(i,0,j,10,0,60),10,80)*7,2)-pow(fuzzyDist(dist(i,0,j,70,0,-60),10,100)*6,2)-fuzzyDist(dist(i,0,j,70,0,-60),50,100)*sin(i-j*i)-fuzzyDist(dist(i,0,j,-10,0,60),70,100)*cos(j);
coordB[i][j][2]=-2*det+j*4;
}
}
}

void makeW(){
for (int i=0;i<det;i++){
for (int j=0;j<det;j++){
coordW[i][j][0]=-200+i*4;
coordW[i][j][1]=0.5*(sin(i-j)+cos(j));
coordW[i][j][2]=-200+j*4;
}
}
}

float giveY(float cx, float cz){
float cy=0;
for (int i=1;i<det;i++){
for (int j=1;j<det;j++){
if ((coordB[i][j][0]-cx<1)&&(coordB[i][j][2]-cz<1)){
cy= coordB[i][j][1];
}
}
}
return cy;
}

void displayB(){
strokeWeight(1);
stroke(255);
fill(230);
strokeWeight(0.1);
beginShape(TRIANGLES);
for (int i=1;i<det;i++){
for (int j=1;j<det;j++){
//line(coord[i][j][0],coord[i][j][1],coord[i][j][2],coord[i][j][0]+0.1,coord[i][j][1]+0.1,coord[i][j][2]+0.1);
vertex(coordB[i][j][0],coordB[i][j][1],coordB[i][j][2]);
vertex(coordB[i][j-1][0],coordB[i][j-1][1],coordB[i][j-1][2]);
vertex(coordB[i-1][j][0],coordB[i-1][j][1],coordB[i-1][j][2]);

vertex(coordB[i][j-1][0],coordB[i][j-1][1],coordB[i][j-1][2]);
vertex(coordB[i-1][j][0],coordB[i-1][j][1],coordB[i-1][j][2]);
vertex(coordB[i-1][j-1][0],coordB[i-1][j-1][1],coordB[i-1][j-1][2]);
}
}
endShape();

}
void displayW(){
strokeWeight(1);
stroke(0,20);
noFill();
strokeWeight(0.1);
beginShape(TRIANGLES);
for (int i=1;i<det;i++){
for (int j=1;j<det;j++){
//line(coord[i][j][0],coord[i][j][1],coord[i][j][2],coord[i][j][0]+0.1,coord[i][j][1]+0.1,coord[i][j][2]+0.1);
vertex(coordW[i][j][0],coordW[i][j][1],coordW[i][j][2]);
vertex(coordW[i][j-1][0],coordW[i][j-1][1],coordW[i][j-1][2]);
vertex(coordW[i-1][j][0],coordW[i-1][j][1],coordW[i-1][j][2]);

vertex(coordW[i][j-1][0],coordW[i][j-1][1],coordW[i][j-1][2]);
vertex(coordW[i-1][j][0],coordW[i-1][j][1],coordW[i-1][j][2]);
vertex(coordW[i-1][j-1][0],coordW[i-1][j-1][1],coordW[i-1][j-1][2]);
}
}
endShape();

}
}

class Drops{
float[][]coord =new float[4][3];
color kolor;
void add(float xs,float  ys,float zs,float xe,float ye,float ze, float ag, float ar, color k){
kolor=k;
//amount=fuzzyDist(dist(loc.x,loc.y,loc.z,go.x,go.y,go.z),1,100);
for(int i = 3;i>0;i–){
coord[i][0]=coord[i-1][0];
coord[i][1]=coord[i-1][1];
coord[i][2]=coord[i-1][2];
}
coord[0][0]=xs;
coord[0][1]=ys;
coord[0][2]=zs;

for(int i = 3;i>0;i–){
coord[i][0]=coord[i-1][0];
coord[i][1]=coord[i-1][1];
coord[i][2]=coord[i-1][2];
}
coord[0][0] = xs + ag*(0.33 * (xe-xs))+ar*(random(-5,5));
coord[0][1] = ys + ag*(pow(0.33, 3) * (ye-ys))+ar*(random(-5,5));
coord[0][2] = zs + ag*(0.33 * (ze-zs))+ar*(random(-5,5));

for(int i = 3;i>0;i–){
coord[i][0]=coord[i-1][0];
coord[i][1]=coord[i-1][1];
coord[i][2]=coord[i-1][2];
}
coord[0][0] = xs + ag*(0.77 * (xe-xs))+ar*(random(-5,5));
coord[0][1] = ys + ag*(pow(0.77, 3) * (ye-ys))+ar*(random(-5,5));
coord[0][2] = zs + ag*(0.77 * (ze-zs))+ar*(random(-5,5));

for(int i = 3;i>0;i–){
coord[i][0]=coord[i-1][0];
coord[i][1]=coord[i-1][1];
coord[i][2]=coord[i-1][2];
}
coord[0][0]=xe;
coord[0][1]=ye;
coord[0][2]=ze;
}

float[] giveCoo(float cx, float cy, float cz){
float[] coo={coord[0][0],coord[0][1],coord[0][2]};
for (int i=1;i<4;i++){
if (dist(cx,cy,cz,coord[i][0],coord[i][1],coord[i][2])<dist(cx,cy,cz,coord[0][0],coord[0][1],coord[0][2])){
coo=coord[i];
}
}
return coo;
}

void display(){
strokeWeight(2);
noFill();
stroke(kolor,60);
for(int i =3; i <4;i+=4){
bezier(coord[i][0],coord[i][1],coord[i][2],coord[i-1][0],coord[i-1][1],coord[i-1][2],coord[i-2][0],coord[i-2][1],coord[i-2][2],coord[i-3][0],coord[i-3][1],coord[i-3][2]);
}

}
}

float fuzzyDist(float dis, int ix, float iy){
float result=0;
float d=dis;
//range
int u1=ix;
float u2=iy;
if(d<=u1){
result=0;
}
else if(d>=u2){
result=1;
}
else{
result=(d /(u2-u1))-(u1/(u2-u1));
}
return result;

}

int nID(float sx,float sy,float sz){
int id=0;
float di = dist(sx,sy,sz,drops[0].coord[1][0],drops[0].coord[1][1],drops[0].coord[1][2]);
for(int i=0;i<currD;i++){
if(dist(sx,sy,sz,drops[i].coord[1][0],drops[0].coord[1][1],drops[0].coord[1][2])<di){
id=i;
}
}
return id;
}

class mFlo{
ArrayList mo;

mFlo() {
mo = new ArrayList();
}

void run(int swi) {
for (int i = 0; i < mo.size(); i++) {
Monkk m = (Monkk) mo.get(i);
m.run(mo,swi);
m.setTheGoal();
}
}

void display(){
for (int i = 0; i < mo.size(); i++) {
Monkk m = (Monkk) mo.get(i);
if (m.on==true){
m.render();
}
}
}

void addMonkk(Monkk m) {
mo.add(m);
}

void changeTarget( Vector3D t){
for (int i = 0; i < mo.size(); i++) {
Monkk m = (Monkk) mo.get(i);
m.newGoal(t);
}
}

}

class Monkk {
int num=1000;
float[]x =new float[num];
float[]y =new float[num];
float[]z =new float[num];
Vector3D loc;
Vector3D vel;
Vector3D acc;
Vector3D go;
float r;
float maxforce;
float maxspeed;
color kolor;
int bCount=0;
int bc=0;
int dc=0;
float amount;
float amountR;
boolean on=false;
float[] gCode;

Monkk(Vector3D l, float ms, float mf, Vector3D g, float[] gc, color c) {
acc = new Vector3D(0,0,0);
vel = new Vector3D(random(-0.5,0.5),random(-0.5,0.5),random(-0.5,0.5));
go=g;
x[0]=l.x;
y[0]=l.y;
z[0]=l.z;
gCode=gc;
loc = l.copy();
r = 2.0f;
maxspeed = ms;
maxforce = mf;
kolor=c;
}

void newGoal(Vector3D g){
go=g;
}

void setTheGoal(){
if (dist(loc.x,loc.y,loc.z,go.x,go.y,go.z)<12){
if(random(0,10)>9){
if (currT==numT){
currT=0;
}
if (loc.y<-50){
float ran=random(-55,55);
targets[currT].add(go.x+ran,beach.giveY(go.x+ran,go.z+ran),go.z+ran,random(10,100));
currT++;
}
else{
targets[currT].add(go.x+random(-12,12),go.y+random(-20,-10),go.z+random(-12,12),random(10,100));
currT++;
}
}
}
}

void run(ArrayList mo, int sw) {
flock(mo);
update();
if (sw==1){

behave(mo);
}

}

void flock(ArrayList mo) {
Vector3D sep = separate(mo);   // Separation
Vector3D ali = align(mo);      // Alignment
Vector3D coh = cohesion(mo);   // Cohesion
sep.mult(2.0f);
ali.mult(1.0f);
coh.mult(1.0f);
acc.add(sep);
acc.add(ali);
acc.add(coh);

}

void update(){
on=true;
for(int i = num-1;i>0;i–){
x[i]=x[i-1];
y[i]=y[i-1];
z[i]=z[i-1];
}
}

void behave(ArrayList mo ) {
amount=(gCode[0]+fuzzyDist(dist(loc.x,loc.y,loc.z,go.x,go.y,go.z),1,100))/2;
x[0]= amount*(x[1]+(-cos(atan2(loc.y-go.y,loc.x-go.x))))+(1-amount)*loc.x-(cos(bCount)*gCode[1]*0.3)-(random(-1,1)*gCode[2]*0.3);
y[0]= amount*(y[1]+(-sin(atan2(loc.y-go.y,loc.x-go.x))))+(1-amount)*loc.y-(sin(bCount)*gCode[1]*0.3)-(random(-1,1)*gCode[2]*0.3);
z[0]= amount*(z[1]+(-cos(atan2(loc.y-go.y,loc.z-go.z))))+(1-amount)*loc.z-(sin(bCount)*gCode[1]*0.3)-(random(-1,1)*gCode[2]*0.3);
if (y[0]>beach.giveY(x[0],z[0])){
y[0]=beach.giveY(x[0],z[0])-1;
}
loc.x=x[0];
loc.y=y[0];
loc.z=z[0];

if(bCount%gCode[5]==1){

for (int i = 0 ; i < mo.size(); i++) {
Monkk other = (Monkk) mo.get(i);
float d = loc.distance(loc,other.loc);
if ((d > 5) && (d < 10)) {
if (currD==numD){
currD=0;
}
if(random(0,10)>3){
if(y[0]<beach.giveY(loc.x,loc.z)){
drops[currD].add(x[0],y[0],z[0],other.x[0],other.y[0],other.z[0],gCode[3],gCode[4],kolor);
currD++;
}
}
}
}
}

if(bCount%gCode[5]==1){
int nearDiD=nID(loc.x,loc.y,loc.z);
float d = dist(loc.x,loc.y,loc.z, drops[nearDiD].giveCoo(loc.x,loc.y,loc.z)[0],drops[nearDiD].giveCoo(loc.x,loc.y,loc.z)[1],drops[nearDiD].giveCoo(loc.x,loc.y,loc.z)[2]);
if ((d > 5) && (d < 15)) {
if (currD==numD){
currD=0;
}
if(random(0,10)>3){
if(y[0]<beach.giveY(loc.x,loc.z)){
drops[currD].add(x[0],y[0],z[0],drops[nearDiD].giveCoo(loc.x,loc.y,loc.z)[0],drops[nearDiD].giveCoo(loc.x,loc.y,loc.z)[1],drops[nearDiD].giveCoo(loc.x,loc.y,loc.z)[2],gCode[3],gCode[4],kolor);
currD++;
}
}
}

}

if(bCount%gCode[6]==1&&loc.y>beach.giveY(loc.x,loc.z)-12){

if (currD==numD){
currD=0;
}
for (int i = 0 ; i < 2; i++) {
if(y[0]<beach.giveY(loc.x,loc.z)){
float di=dist(loc.x,loc.y,loc.z,loc.x,beach.giveY(loc.x,loc.z),loc.z);
float ra =random(-di,di);
drops[currD].add(loc.x,loc.y,loc.z,loc.x-ra,beach.giveY(loc.x+ra,loc.z+ra),loc.z-ra,gCode[3],gCode[4],kolor);
currD++;
}

}
}

vel.add(acc);
vel.limit(maxspeed);
loc.add(vel);
acc.setXYZ(0,0,0);
bCount++;

}

void seek(Vector3D target) {
acc.add(steer(target,false));
}

void arrive(Vector3D target) {
acc.add(steer(target,true));
}

Vector3D steer(Vector3D target, boolean slowdown) {
Vector3D steer;
Vector3D desired = target.sub(target,loc);
float d = desired.magnitude();
if (d > 0) {
desired.normalize();
if ((slowdown) && (d < 100.0f)) desired.mult(maxspeed*(d/100.0f));
else desired.mult(maxspeed);
steer = target.sub(desired,vel);
steer.limit(maxforce);
} else {
steer = new Vector3D(0,0,0);
}
return steer;
}

void render() {

noFill();
stroke(kolor,50);
strokeWeight(2);
beginShape();
for(int i =0; i <num;i++){
vertex(x[i],y[i],z[i]);

}
endShape();

}

// Separation
Vector3D separate (ArrayList mo) {
float desiredseparation = 0.5f;
Vector3D sum = new Vector3D(0,0,0);
int count = 0;
for (int i = 0 ; i < mo.size(); i++) {
Monkk other = (Monkk) mo.get(i);
float d = loc.distance(loc,other.loc);
if ((d > 0) && (d < desiredseparation)) {
Vector3D diff = loc.sub(loc,other.loc);
diff.normalize();
diff.div(d);
sum.add(diff);
count++;
}
}
if (count > 0) {
sum.div((float)count);
}
return sum;
}

// Alignment
Vector3D align (ArrayList mo) {
float neighbordist = 1.0f;
Vector3D sum = new Vector3D(0,0,0);
int count = 0;
for (int i = 0 ; i < mo.size(); i++) {
Monkk other = (Monkk) mo.get(i);
float d = loc.distance(loc,other.loc);
if ((d > 0) && (d < neighbordist)) {
sum.add(other.vel);
count++;
}
}
if (count > 0) {
sum.div((float)count);
sum.limit(maxforce);
}
return sum;
}

// Cohesion
Vector3D cohesion (ArrayList mo) {
float neighbordist = 50.0f;
Vector3D sum = new Vector3D(0,0,0);
int count = 0;
for (int i = 0 ; i < mo.size(); i++) {
Monkk other = (Monkk) mo.get(i);
float d = loc.distance(loc,other.loc);
if ((d > 0) && (d < neighbordist)) {
sum.add(other.loc);
count++;
}
}
if (count > 0) {
sum.div((float)count);
return steer(sum,false);
}
return sum;
}

}

class Targets{
float x;
float y;
float z;
float range;
boolean on=false;

void add(float ax, float ay, float az, float r){
x=ax;
y=ay;
z=az;
range=r;
on=true;
mflo.changeTarget(new Vector3D(targets[currT].x,targets[currT].y,targets[currT].z));
}

void display(){
if (on==true){
pushMatrix();
translate(x,y,z);
fill(255,0,0,50);
noStroke();
sphere(1);
popMatrix();
}
}
}
static class Vector3D {
float x;
float y;
float z;

Vector3D(float x_, float y_, float z_) {
x = x_; y = y_; z = z_;
}

Vector3D(float x_, float y_) {
x = x_; y = y_; z = 0f;
}

Vector3D() {
x = 0f; y = 0f; z = 0f;
}

void setX(float x_) {
x = x_;
}

void setY(float y_) {
y = y_;
}

void setZ(float z_) {
z = z_;
}

void setXY(float x_, float y_) {
x = x_;
y = y_;
}

void setXYZ(float x_, float y_, float z_) {
x = x_;
y = y_;
z = z_;
}

void setXYZ(Vector3D v) {
x = v.x;
y = v.y;
z = v.z;
}

float magnitude() {
return (float) Math.sqrt(x*x + y*y + z*z);
}

Vector3D copy() {
return new Vector3D(x,y,z);
}

Vector3D copy(Vector3D v) {
return new Vector3D(v.x, v.y,v.z);
}

void add(Vector3D v) {
x += v.x;
y += v.y;
z += v.z;
}

void sub(Vector3D v) {
x -= v.x;
y -= v.y;
z -= v.z;
}

void mult(float n) {
x *= n;
y *= n;
z *= n;
}

void div(float n) {
x /= n;
y /= n;
z /= n;
}

void normalize() {
float m = magnitude();
if (m > 0) {
div(m);
}
}

void limit(float max) {
if (magnitude() > max) {
normalize();
mult(max);
}
}

float heading2D() {
float angle = (float) Math.atan2(-y, x);
return -1*angle;
}

Vector3D add(Vector3D v1, Vector3D v2) {
Vector3D v = new Vector3D(v1.x + v2.x,v1.y + v2.y, v1.z + v2.z);
return v;
}

Vector3D sub(Vector3D v1, Vector3D v2) {
Vector3D v = new Vector3D(v1.x – v2.x,v1.y – v2.y,v1.z – v2.z);
return v;
}

Vector3D div(Vector3D v1, float n) {
Vector3D v = new Vector3D(v1.x/n,v1.y/n,v1.z/n);
return v;
}

Vector3D mult(Vector3D v1, float n) {
Vector3D v = new Vector3D(v1.x*n,v1.y*n,v1.z*n);
return v;
}

float distance (Vector3D v1, Vector3D v2) {
float dx = v1.x – v2.x;
float dy = v1.y – v2.y;
float dz = v1.z – v2.z;
return (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
}

}

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s