Matt evans, gordon lai + chris ward

From KokkugiaWiki

Board 1:
Image:Row_B_001_sm2.JPG
Iteration 3:
Image:StrVolSkin005cS.jpg
Iteration 2:
Image:StrVolSkin004bS.jpg
Iteration 1:
Image:StrVolSkin003S.jpg
LATEST CODE:

import kGeom.*;
import kRender.*;

PrintWriter output;
kSpace space;

kWorld world1;
float envSize = 300;


void setup(){
  size(500,500,P3D);
  frameRate(50);
  
  space = new kSpace(this);
  space.cam.jump(-600,-550,-500);
  
  world1 = new kWorld();
    
  // create structure
  for (int i = 0; i < 1000; i++) {
    world1.addAgentStructure(new kAgentStructure(new kVec(random(-250,250),random(-250,250),random(-250,250)), new kVec(random(-1,1),random(-1,1),random(-1,1)), 10, 0.5));
  }
  //create volume
  for (int i = 0; i < 5; i++) {
    world1.addAgentVolume(new kAgentVolume(new kVec(random(-250,250),random(-250,250),random(-250,250)), new kVec(random(-1,1),random(-1,1),random(-1,1)), 0.5, 0.06));
  }
  //create skin
  for (int i = 0; i < 500; i++) {
    world1.addAgentSkin(new kAgentSkin(new kVec(random(-250,250),random(-250,250),random(-250,250)), new kVec(random(-1,1),random(-1,1),random(-1,1)), 5, 0.06));
  }
     
}


void draw(){
  
  background(255);

  int mx = mouseX;
  int my = mouseY;
  
  world1.run();
  
  kRange rng = new kRange(300);
  rng.setColor(100); 
  space.append(rng);
  
  if (mousePressed) {
    exportToTxt();
  }
  
  space.render();
  space.init();
   
}

void mouseDragged(){
  space.mouseDragged();
}

void exportToTxt() {  
  output = createWriter("networkExport.txt"); 
 
  for (int i = 0; i < world1.lines.size(); i++) {  // LINES
    kLine l = (kLine) world1.lines.get(i);   
    kVec start = l.StartPoint();
    kVec end = l.EndPoint();
    output.println(start.x + "," + start.y + "," + start.z + " " + end.x + "," + end.y + "," + end.z);
  }

 output.flush();
 output.close();
}

// kAGent
// simple 3D agent class - based on code from dan shiffman
// roland snooks | kokkugia.com | 2007


class kAgent{
  
 kVec         acc;
 kVec         vel;
 kVec         pos;
 kVec         vec;
 float        maxVel;
 float        maxForce;
 float        sepScale;
 float        aliScale;
 float        cohScale;
 float        rangeOfVision;

 float        wandertheta;
 
 float        attOffset = 200;
 float        ht = envSize*2;
 int          drawColor;
 
 String       agentType = "kAgent";
   
 kVec sumSep = new kVec(0,0,0);
 
 // constructor simple
 kAgent(
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce){
   
   acc = new kVec(0,0,0);
   vel = new kVec(random(-1,1),random(-1,1),random(-1,1));    
   pos = kVec.clone(_pos);
   vec = kVec.clone(_vec);
   maxVel = _maxVel;
   maxForce = _maxForce;
   
   sepScale = 7;
   aliScale = 0.7;
   cohScale = 1;
    
   rangeOfVision = 70; 

   drawColor = 255;
   
 }
 
 // constructor complete
  kAgent(
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce,
     kVec _vel,
     float _sepScale,
     //float _aliScale, //**
     float _cohScale,
     float _rangeOfVision){
   
   acc = new kVec(0,0,0);
   vel = kVec.clone(_vel);    
   pos = kVec.clone(_pos);
   vec = kVec.clone(_vec);
   maxVel = _maxVel;
   maxForce = _maxForce;
   
   sepScale = _sepScale;
   //aliScale = _aliScale; //**
   cohScale = _cohScale;
    
   rangeOfVision = _rangeOfVision; 
   drawColor = 255;
 }
 
 
 // calculates new location
 void step(kWorld world){ 
   
    updatePop(world);
    
    vel.plus(acc);
    vel.limit(maxVel);  
    pos.plus(vel);
    acc = new kVec(0,0,0);  // reset acc to 0 each iteration
      
    borders(envSize);
    render();
    
 }
 
 
 void updatePop(kWorld world){  
    
    
  }    


 // steer
 kVec steer(kVec target, float threshold) {
    target.minus(pos); 
    float dist = target.length();

    if (dist > 0 && dist < threshold) {
      target.normalize();
      target.scale(maxVel);
      target.minus(vel); 
      target.limit(maxForce); 
    } 
    else {
      target = new kVec(0,0,0);
    }
    return target;
  }


  // seek
  void seek(kVec target, float threshold) {
    acc.plus(steer(target, threshold));
  }
   
   
// separation
  kVec separate (ArrayList pop, float sepDist) {
    kVec sum = new kVec(0,0,0);
    int count = 0;

    for (int i = 0 ; i < pop.size(); i++) {
      kAgent other = (kAgent) pop.get(i);
      float dist = pos.distance(other.pos);
      
      if ((dist > 0) && (dist < sepDist)) {
        kVec diff = kVec.clone(pos); 
        diff.minus(other.pos);
        diff.normalize();
        diff.scale(1/dist);          
        sum.plus(diff);
        count++;                     
      }
    }
    if (count > 0) {
      sum.scale(1/(float)count);
    }
    sumSep = kVec.clone(sum);
    return sum;
  }
 
 
  // alignment
  kVec align (ArrayList pop) {
    kVec sum = new kVec(0,0,0);
    int count = 0;
    for (int i = 0 ; i < pop.size(); i++) {
      kAgent other = (kAgent) pop.get(i);
      float dist = pos.distance(other.pos);
      if ((dist > 0) && (dist < rangeOfVision)) {
        sum.plus(other.vel);
        count++;
      }
    }
    if (count > 0) {
      sum.scale(1/(float)count);
      sum.limit(maxForce);
    }
    return sum;
  }


  // cohesion
  kVec cohesion (ArrayList pop) {
    kVec sum = new kVec(0,0,0);   
    int count = 0;
    for (int i = 0 ; i < pop.size(); i++) {
      kAgent other = (kAgent) pop.get(i);
      float dist = pos.distance(other.pos);
      if ((dist > 0) && (dist < rangeOfVision)) {
        sum.plus(other.pos); 
        count++;
      }
    }
    if (count > 0) {
      sum.scale(1/(float)count);
      return steer(sum, ht);
    }
    return sum;
  }


  void render() {

    // draw vectors  
    float vecDisScale = 2;
    
    kLine ln = new kLine(pos, vel, vel.length()*vecDisScale);   // LINES
    ln.setColor(255,0,0);
    //space.append(ln);

    kLine ln1 = new kLine(pos, sumSep, sumSep.length()*vecDisScale);
    ln1.setColor(0,0,255);
    //space.append(ln1);
    
    // draw agent
    kLine ln2 = new kLine(pos, vel, 3);
    ln2.setColor(drawColor);
    space.append(ln2);

  }
  
  void network(ArrayList pop, float threshold){
    //loop through all the agents and check their distance

    float closestDist = 1000000;
    int closestAgent = 0;
    int count = 0;

    for(int i = 0; i < pop.size(); i++){
      kAgent other = (kAgent) pop.get(i);
      float dist = pos.distance(other.pos);
      if(dist < threshold){
        
        if(i == 0 && dist > 0){
          closestDist = dist;
          closestAgent = 0;
          count++;
        }else{
          if(dist < closestDist && dist > 0){
            closestDist = dist;
            closestAgent = i;
            count++;
          }
        }
      } 
    }

    if(count > 0){
      kAgent other = (kAgent) pop.get(closestAgent);
      kLine l = new kLine(pos, other.pos);
      l.setColor(150);  
      space.append(l);
      world1.addLine(l);  
    }

  }
  
  void borders(float envSize) {
    if (pos.x < -envSize) pos.x = envSize;
    if (pos.y < -envSize) pos.y = envSize;
    if (pos.z < -envSize) pos.z = envSize;
    if (pos.x > envSize) pos.x = -envSize;
    if (pos.y > envSize) pos.y = -envSize;
    if (pos.z > envSize) pos.z = -envSize;
    
  }
}
// kAgentStructure
class kAgentSkin extends kAgent{
   
 kAgentSkin(     
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce){
       
  super(
     _pos, 
     _vec, 
     _maxVel,
     _maxForce);
     
     drawColor = 0;
     agentType = "kAgentStructure";
  }

    void updatePop(kWorld world){  
    float sepVolScale = 2; 

    kVec seekVol = seekStructure(world.volume);

    // call population functions
    kVec sepVol = separate(world.volume, 1000);  // 100
    kVec sep = separate(world.skin, 2000);  // 20
    kVec coh = cohesion(world.skin);   

    // weight vector
    seekVol.scale(1);
    sepVol.scale(100); // 100
    sep.scale(10); // 10
    coh.scale(.065);

    // add the vectors to acceleration
    acc.plus(seekVol);
    acc.plus(sepVol);
    acc.plus(sep);
    acc.plus(coh);

  }
 
  /*   // seek closest agent
    kAgent other = (kAgent) pop.get(closestAgent);
    kVec target = kVec.clone(other.pos);
    
    this.seek(target, 300);
  }*/
  
   // seek volume
  kVec seekStructure(ArrayList vol){
    // return a vector for seeking the volumes
    // find closest agent
    float closestDist = envSize*envSize;
    int closestAgent = 0;
    for(int i = 0; i<vol.size(); i++){
      kAgent other = (kAgent) vol.get(i);
      float dist = pos.distance(other.pos);
      if(i > 0){
        if(dist < closestDist && dist > 100){
          closestDist = dist;
          closestAgent = i;
        }
      }
      else{
        closestDist = dist;
        closestAgent = 0;
      }

    }

    // seek closest agent
    kAgent other = (kAgent) vol.get(closestAgent);
    kVec target = kVec.clone(other.pos);

    return steer(target, 300); //300
  }
 
   void render() {

    // draw vectors  
    float vecDisScale = 2;
    
    /*kLine ln = new kLine(pos, vel, vel.length()*vecDisScale);
    ln.setColor(255,0,0);
    //space.append(ln);

    kLine ln1 = new kLine(pos, sumSep, sumSep.length()*vecDisScale);
    ln1.setColor(0,0,255);
    //space.append(ln1);
    
    // draw agent
    kLine ln2 = new kLine(pos, vel, 3);
    ln2.setColor(0);
    space.append(ln2);*/
    
    // skin color
    float attDisScale = 2;
    kLine ln0 = new kLine(pos.x,pos.y,pos.z - attDisScale,pos.x,pos.y,pos.z + attDisScale);
    //kLine ln1a = new kLine(pos.x,pos.y - attDisScale,pos.z,pos.x,pos.y + attDisScale,pos.z);
    //kLine ln2a = new kLine(pos.x - attDisScale,pos.y,pos.z,pos.x + attDisScale,pos.y,pos.z);
    
    ln0.setColor(0,200,0);
    //ln1a.setColor(0,200,0);
    //ln2a.setColor(0,200,0);
    
    space.append(ln0);
    //space.append(ln1a);
    //space.append(ln2a);
  }
  
}
// kAgentSkin
class kAgentStructure extends kAgent{
   
 kAgentStructure(     
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce){
       
  super(
     _pos, 
     _vec, 
     _maxVel,
     _maxForce);
     
     
     drawColor = 0;
     agentType = "kAgentStructure";
     rangeOfVision = 100;
  }
 
 
   void updatePop(kWorld world){  
    float sepVolScale = 2; 

    kVec seekVol = seekStructure(world.volume);

    // call population functions
    kVec sepVol = separate(world.volume, 100);  // 100
    kVec sep = separate(world.skin, 20);  // 20
    kVec coh = cohesion(world.skin);   

    // weight vector
    seekVol.scale(100);
    sepVol.scale(1200);
    sep.scale(1200);
    coh.scale(.095);

    // add the vectors to acceleration
    acc.plus(seekVol);
    acc.plus(sepVol);
    acc.plus(sep);
    acc.plus(coh);

  }
 
  /*   // seek closest agent
    kAgent other = (kAgent) pop.get(closestAgent);
    kVec target = kVec.clone(other.pos);
    
    this.seek(target, 300);
  }*/
  
   // seek volume
  kVec seekStructure(ArrayList vol){
    // return a vector for seeking the volumes
    // find closest agent
    float closestDist = envSize*envSize;
    int closestAgent = 0;
    for(int i = 0; i<vol.size(); i++){
      kAgent other = (kAgent) vol.get(i);
      float dist = pos.distance(other.pos);
      if(i > 0){
        if(dist < closestDist && dist > 100){
          closestDist = dist;
          closestAgent = i;
        }
      }
      else{
        closestDist = dist;
        closestAgent = 0;
      }

    }

    // seek closest agent
    kAgent other = (kAgent) vol.get(closestAgent);
    kVec target = kVec.clone(other.pos);

    return steer(target, 300); //300
  }
 
   void render() {

    // draw vectors  
    float vecDisScale = 5;
     // structure connecting lines
    kLine ln = new kLine(pos, vel, vel.length()*vecDisScale);
    ln.setColor(255,0,0);
    //space.append(ln);

    kLine ln1 = new kLine(pos, sumSep, sumSep.length()*vecDisScale);
    ln1.setColor(0,0,255);
    //space.append(ln1);
    
    // draw agent
    kLine ln2 = new kLine(pos, vel, 3);
    ln2.setColor(0);
    space.append(ln2);
    
    // strucure color
    float attDisScale = 1;
    kLine ln0 = new kLine(pos.x,pos.y,pos.z - attDisScale,pos.x,pos.y,pos.z + attDisScale);
    
    ln0.setColor(0,0,0);
    
    space.append(ln0);
   }
  
}
//kAgentVolume
class kAgentVolume extends kAgent{
   
 kAgentVolume(     
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce){
       
  super(
     _pos, 
     _vec, 
     _maxVel,
     _maxForce);
     
     drawColor = 0;
     agentType = "kAgentVolume";
  }
 
 
 void updatePop(ArrayList pop){  
    
    // call population functions
    kVec sep = separate(pop, 50);   
    kVec ali = align(pop);      
    kVec coh = cohesion(pop);   
    
    // weight vector
    sep.scale(sepScale);
    ali.scale(aliScale);
    coh.scale(cohScale);
    
    // add the vectors to acceleration
    acc.plus(sep);
    acc.plus(ali); //**
    acc.plus(coh);
    
  }    
 
 
  void render(){
    float attDisScale = 5;
    kLine ln0 = new kLine(pos.x,pos.y,pos.z - attDisScale,pos.x,pos.y,pos.z + attDisScale);
    kLine ln1 = new kLine(pos.x,pos.y - attDisScale,pos.z,pos.x,pos.y + attDisScale,pos.z);
    kLine ln2 = new kLine(pos.x - attDisScale,pos.y,pos.z,pos.x + attDisScale,pos.y,pos.z);
    
    ln0.setColor(0,0,255);
    ln1.setColor(0,0,255);
    ln2.setColor(0,0,255);
    
    space.append(ln0);
    space.append(ln1);
    space.append(ln2);
    
  }  

  
}
// kAgentWorld
// a class which controls the agent population arraylist

class kWorld {
  ArrayList lines; // LINES
  ArrayList volume;
  ArrayList structure;
  ArrayList skin;
  
  kWorld() {
     lines = new ArrayList();  // LINES
     volume = new ArrayList();
     structure = new ArrayList();
     skin = new ArrayList();
  }

  // cycles through each agent passing the population to it
  void run(){
    for (int i = 0; i < volume.size(); i++) {
      kAgent a = (kAgent) volume.get(i);  
      a.step(this); 
    }
    
    for (int i = 0; i < structure.size(); i++) {
      kAgent a = (kAgent) structure.get(i);  
      a.step(this); 
    }
    
    for (int i = 0; i < skin.size(); i++) {
      kAgent a = (kAgent) skin.get(i);  
      a.step(this); 
    }
    
    lines = new ArrayList();
    for (int i = 0; i < structure.size(); i++) {
      kAgent a = (kAgent) structure.get(i);  
      //a.network(world.population, 50, 5);
      a.network(structure, 100);
    }
  }

  // adds an agent to the population
  void addAgentVolume(kAgent a) {
    volume.add(a);
  }
  
    void addAgentSkin(kAgent a) {
    skin.add(a);
  }
  
    void addAgentStructure(kAgent a) {
    structure.add(a);
  }
  
  // adds a line to lines  // LINES
  void addLine(kLine l) { 
    lines.add(l);
  } 
}

Image:Structure&Volume.jpg Image:Wle_49_steps_20080325.png Image:Wle_49_steps_20080325_rend.png Image:Wle_49_steps_20080325_rend_a.png

import kGeom.*;
import kRender.*;

PrintWriter output;
kSpace space;

kWorld world1;
float envSize = 300;


void setup(){
  size(500,500,P3D);
  frameRate(50);
  
  space = new kSpace(this);
  space.cam.jump(-600,-550,-500);
  
  world1 = new kWorld();
    
  // create agents
  for (int i = 0; i < 300; i++) {
    world1.addAgentSkin(new kAgentSkin(new kVec(random(-250,250),random(-250,250),random(-250,250)), new kVec(random(-1,1),random(-1,1),random(-1,1)), 10, 0.5));
  }
  
  
  for (int i = 0; i < 5; i++) {
    world1.addAgentVolume(new kAgentVolume(new kVec(random(-250,250),random(-250,250),random(-250,250)), new kVec(random(-1,1),random(-1,1),random(-1,1)), 0.5, 0.06));
  }
     
}


void draw(){
  
  background(255);

  int mx = mouseX;
  int my = mouseY;
  
  world1.run();
  
  kRange rng = new kRange(300);
  rng.setColor(100); 
  space.append(rng);
  
  if (mousePressed) {
    exportToTxt();
  }
  
  space.render();
  space.init();
   
}

void mouseDragged(){
  space.mouseDragged();
}

void exportToTxt() {  
  output = createWriter("networkExport.txt"); 
 
  for (int i = 0; i < world1.lines.size(); i++) {  // LINES
    kLine l = (kLine) world1.lines.get(i);   
    kVec start = l.StartPoint();
    kVec end = l.EndPoint();
    output.println(start.x + "," + start.y + "," + start.z + " " + end.x + "," + end.y + "," + end.z);
  }

 output.flush();
 output.close();
}


// kAGent
// simple 3D agent class - based on code from dan shiffman
// roland snooks | kokkugia.com | 2007


class kAgent{
  
 kVec         acc;
 kVec         vel;
 kVec         pos;
 kVec         vec;
 float        maxVel;
 float        maxForce;
 float        sepScale;
 float        aliScale;
 float        cohScale;
 float        rangeOfVision;

 float        wandertheta;
 
 float        attOffset = 200;
 float        ht = envSize*2;
 int          drawColor;
 
 String       agentType = "kAgent";
   
 kVec sumSep = new kVec(0,0,0);
 
 // constructor simple
 kAgent(
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce){
   
   acc = new kVec(0,0,0);
   vel = new kVec(random(-1,1),random(-1,1),random(-1,1));    
   pos = kVec.clone(_pos);
   vec = kVec.clone(_vec);
   maxVel = _maxVel;
   maxForce = _maxForce;
   
   sepScale = 7;
   aliScale = 0.7;
   cohScale = 1;
    
   rangeOfVision = 70; 

   drawColor = 255;
   
 }
 
 // constructor complete
  kAgent(
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce,
     kVec _vel,
     float _sepScale,
     //float _aliScale, //**
     float _cohScale,
     float _rangeOfVision){
   
   acc = new kVec(0,0,0);
   vel = kVec.clone(_vel);    
   pos = kVec.clone(_pos);
   vec = kVec.clone(_vec);
   maxVel = _maxVel;
   maxForce = _maxForce;
   
   sepScale = _sepScale;
   //aliScale = _aliScale; //**
   cohScale = _cohScale;
    
   rangeOfVision = _rangeOfVision; 
   drawColor = 255;
 }
 
 
 // calculates new location
 void step(kWorld world){ 
   
    updatePop(world);
    
    vel.plus(acc);
    vel.limit(maxVel);  
    pos.plus(vel);
    acc = new kVec(0,0,0);  // reset acc to 0 each iteration
      
    borders(envSize);
    render();
    
 }
 
 
 void updatePop(kWorld world){  
    
    
  }    


 // steer
 kVec steer(kVec target, float threshold) {
    target.minus(pos); 
    float dist = target.length();

    if (dist > 0 && dist < threshold) {
      target.normalize();
      target.scale(maxVel);
      target.minus(vel); 
      target.limit(maxForce); 
    } 
    else {
      target = new kVec(0,0,0);
    }
    return target;
  }


  // seek
  void seek(kVec target, float threshold) {
    acc.plus(steer(target, threshold));
  }
   
   
// separation
  kVec separate (ArrayList pop) {
    kVec sum = new kVec(0,0,0);
    int count = 0;

    for (int i = 0 ; i < pop.size(); i++) {
      kAgent other = (kAgent) pop.get(i);
      float dist = pos.distance(other.pos);
      
      if ((dist > 0) && (dist < rangeOfVision/1.5)) {
        kVec diff = kVec.clone(pos); 
        diff.minus(other.pos);
        diff.normalize();
        diff.scale(1/dist);          
        sum.plus(diff);
        count++;                     
      }
    }
    if (count > 0) {
      sum.scale(1/(float)count);
    }
    sumSep = kVec.clone(sum);
    return sum;
  }
 
 
  // alignment
  kVec align (ArrayList pop) {
    kVec sum = new kVec(0,0,0);
    int count = 0;
    for (int i = 0 ; i < pop.size(); i++) {
      kAgent other = (kAgent) pop.get(i);
      float dist = pos.distance(other.pos);
      if ((dist > 0) && (dist < rangeOfVision)) {
        sum.plus(other.vel);
        count++;
      }
    }
    if (count > 0) {
      sum.scale(1/(float)count);
      sum.limit(maxForce);
    }
    return sum;
  }


  // cohesion
  kVec cohesion (ArrayList pop) {
    kVec sum = new kVec(0,0,0);   
    int count = 0;
    for (int i = 0 ; i < pop.size(); i++) {
      kAgent other = (kAgent) pop.get(i);
      float dist = pos.distance(other.pos);
      if ((dist > 0) && (dist < rangeOfVision)) {
        sum.plus(other.pos); 
        count++;
      }
    }
    if (count > 0) {
      sum.scale(1/(float)count);
      return steer(sum, ht);
    }
    return sum;
  }


  void render() {

    // draw vectors  
    float vecDisScale = 2;
    
    kLine ln = new kLine(pos, vel, vel.length()*vecDisScale);   // LINES
    ln.setColor(255,0,0);
    space.append(ln);

    kLine ln1 = new kLine(pos, sumSep, sumSep.length()*vecDisScale);
    ln1.setColor(0,0,255);
    space.append(ln1);
    
    // draw agent
    kLine ln2 = new kLine(pos, vel, 3);
    ln2.setColor(drawColor);
    space.append(ln2);

  }
  
  void network(ArrayList pop, float threshold){
    //loop through all the agents and check their distance

    float closestDist = 1000000;
    int closestAgent = 0;
    int count = 0;

    for(int i = 0; i < pop.size(); i++){
      kAgent other = (kAgent) pop.get(i);
      float dist = pos.distance(other.pos);
      if(dist < threshold){
        
        if(i == 0 && dist > 0){
          closestDist = dist;
          closestAgent = 0;
          count++;
        }else{
          if(dist < closestDist && dist > 0){
            closestDist = dist;
            closestAgent = i;
            count++;
          }
        }
      } 
    }

    if(count > 0){
      kAgent other = (kAgent) pop.get(closestAgent);
      kLine l = new kLine(pos, other.pos);
      l.setColor(150);  
      space.append(l);
      world1.addLine(l);  
    }

  }
  
  void borders(float envSize) {
    if (pos.x < -envSize) pos.x = envSize;
    if (pos.y < -envSize) pos.y = envSize;
    if (pos.z < -envSize) pos.z = envSize;
    if (pos.x > envSize) pos.x = -envSize;
    if (pos.y > envSize) pos.y = -envSize;
    if (pos.z > envSize) pos.z = -envSize;
    
  }
}
// kAgentSkin
class kAgentSkin extends kAgent{
   
 kAgentSkin(     
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce){
       
  super(
     _pos, 
     _vec, 
     _maxVel,
     _maxForce);
     
     
     drawColor = 0;
     agentType = "kAgentStructure";
  }
 
 
   void updatePop(kWorld world){  
    float sepVolScale = 2; 
    
     //kVec seekVol = seekVolume(world.volume);
     
    // call population functions
    kVec sepVol = separate(world.volume);  
    kVec sep = separate(world.skin);  
    kVec coh = cohesion(world.skin);   
    
    // weight vector
    //seekVol.scale(seekVolScale);
    sepVol.scale(sepVolScale);
    sep.scale(sepScale);
    coh.scale(cohScale);
    
    // add the vectors to acceleration
    //acc.plus(seekVol);
    acc.plus(sepVol);
    acc.plus(sep);
    acc.plus(coh);
    
  }  
 
 
  // seek volume
  kVec seekVolume(){
    // return a vector for seeking the volumes
    return new kVec(0,0,0);
  }
 
 
   void render() {

    // draw vectors  
    float vecDisScale = 2;
    
    kLine ln = new kLine(pos, vel, vel.length()*vecDisScale);
    ln.setColor(255,0,0);
    space.append(ln);

    kLine ln1 = new kLine(pos, sumSep, sumSep.length()*vecDisScale);
    ln1.setColor(0,0,255);
    //space.append(ln1);
    
    // draw agent
    kLine ln2 = new kLine(pos, vel, 3);
    ln2.setColor(0);
    space.append(ln2);

  }
  
}
// kAgentStructure
class kAgentStructure extends kAgent{
   
 kAgentStructure(     
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce){
       
  super(
     _pos, 
     _vec, 
     _maxVel,
     _maxForce);
     
     drawColor = 0;
     agentType = "kAgentStructure";
  }
 
 
  void updatePop(ArrayList pop){  
    
   // seek pray
   // find closest agent
   float closestDist = envSize*envSize;
   int closestAgent = 0;
   for(int i = 0; i<pop.size(); i++){
     kAgent other = (kAgent) pop.get(i);
     if(other.agentType == "kAgent"){
       float dist = pos.distance(other.pos);
       if(i > 0){
         if(dist < closestDist){
           closestDist = dist;
           closestAgent = i;
         }
           
       }else{
         closestDist = dist;
         closestAgent = 0;
       }
     }

   }
    
    // seek closest agent
    kAgent other = (kAgent) pop.get(closestAgent);
    kVec target = kVec.clone(other.pos);
    
    this.seek(target, 300);
  } 
 
 
   void render() {

    // draw vectors  
    float vecDisScale = 2;
    
    kLine ln = new kLine(pos, vel, vel.length()*vecDisScale);
    ln.setColor(255,0,0);
    space.append(ln);

    kLine ln1 = new kLine(pos, sumSep, sumSep.length()*vecDisScale);
    ln1.setColor(0,0,255);
    //space.append(ln1);
    
    // draw agent
    kLine ln2 = new kLine(pos, vel, 3);
    ln2.setColor(0);
    space.append(ln2);

  }
  
}
//kAgentVolume
class kAgentVolume extends kAgent{
   
 kAgentVolume(     
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce){
       
  super(
     _pos, 
     _vec, 
     _maxVel,
     _maxForce);
     
     drawColor = 0;
     agentType = "kAgentVolume";
  }
 
 
 void updatePop(ArrayList pop){  
    
    // call population functions
    kVec sep = separate(pop);   
    kVec ali = align(pop);      
    kVec coh = cohesion(pop);   
    
    // weight vector
    sep.scale(sepScale);
    ali.scale(aliScale);
    coh.scale(cohScale);
    
    // add the vectors to acceleration
    acc.plus(sep);
    acc.plus(ali); //**
    acc.plus(coh);
    
  }    
 
 
  void render(){
    float attDisScale = 5;
    kLine ln0 = new kLine(pos.x,pos.y,pos.z - attDisScale,pos.x,pos.y,pos.z + attDisScale);
    kLine ln1 = new kLine(pos.x,pos.y - attDisScale,pos.z,pos.x,pos.y + attDisScale,pos.z);
    kLine ln2 = new kLine(pos.x - attDisScale,pos.y,pos.z,pos.x + attDisScale,pos.y,pos.z);
    
    ln0.setColor(0,0,255);
    ln1.setColor(0,0,255);
    ln2.setColor(0,0,255);
    
    space.append(ln0);
    space.append(ln1);
    space.append(ln2);
    
  }  

  
}
// kAgentWorld
// a class which controls the agent population arraylist

class kWorld {
  ArrayList lines; // LINES
  ArrayList volume;
  ArrayList structure;
  ArrayList skin;
  
  kWorld() {
     lines = new ArrayList();  // LINES
     volume = new ArrayList();
     structure = new ArrayList();
     skin = new ArrayList();
  }

  // cycles through each agent passing the population to it
  void run(){
    for (int i = 0; i < volume.size(); i++) {
      kAgent a = (kAgent) volume.get(i);  
      a.step(this); 
    }
    
    for (int i = 0; i < structure.size(); i++) {
      kAgent a = (kAgent) structure.get(i);  
      a.step(this); 
    }
    
    for (int i = 0; i < skin.size(); i++) {
      kAgent a = (kAgent) skin.get(i);  
      a.step(this); 
    }
    
    lines = new ArrayList();
    for (int i = 0; i < skin.size(); i++) {
      kAgent a = (kAgent) skin.get(i);  
      //a.network(world.population, 50, 5);
      a.network(skin, 100);
    }
  }

  // adds an agent to the population
  void addAgentVolume(kAgent a) {
    volume.add(a);
  }
  
    void addAgentStructure(kAgent a) {
    structure.add(a);
  }
  
    void addAgentSkin(kAgent a) {
    skin.add(a);
  }
  
  // adds a line to lines  // LINES
  void addLine(kLine l) { 
    lines.add(l);
  } 
}

Image:kAgent_Diagram_003.jpg


import kGeom.*;
import kRender.*;

kSpace space;

kWorld world1;
float envSize = 300;

void setup(){
  size(500,500,P3D);
  frameRate(50);
  
  space = new kSpace(this);
  space.cam.jump(-600,-550,-500);
  
  world1 = new kWorld();
  
  // create agents
  for (int i = 0; i < 300; i++) {
    world1.addAgent(new kAgentPrey(new kVec(random(-250,250),random(-250,250),random(-250,250)), new kVec(random(-1,1),random(-1,1),random(-1,1)), 4, 0.2));
  }

  for (int i = 0; i < 10; i++) {
    world1.addAgent(new kAgentPredator(new kVec(random(-250,250),random(-250,250),random(-250,250)), new kVec(random(-1,1),random(-1,1),random(-1,1)), 12, 0.06));
  }
  
  for (int i = 0; i < 100; i++) {
      world1.addAgent(new kAgent(new kVec(random(500),random(500),random(500)), new kVec(random(-1,1),random(-1,1), random(-1,1)), 1, 0.2));
    }

}

void draw(){
  
  background(255);

  int mx = mouseX;
  int my = mouseY;
   
  world1.run();
  
  kRange rng = new kRange(300);
  rng.setColor(100); 
  space.append(rng);
  // if target distance < 20 then deleteAgent()
  /*if() {
    
  }*/
  
  space.render();
  space.init();
}


void mouseDragged(){
  space.mouseDragged();
}

class kAgent{
 kVec         acc;
 kVec         vel;
 kVec         pos;
 kVec         vec;
 float        maxVel;
 float        maxForce;
 float        sepScale;
 float        aliScale;
 float        cohScale;
 float        rangeOfVision;
 float        wandertheta;
 float        attOffset = 200;
 float        ht = envSize*2;
 int          drawColor;
 String       agentType = "kAgent";
 
 kVec sumSep = new kVec(0,0,0);
 
 // constructor simple
 kAgent(
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce){

   acc = new kVec(0,0,0);
   vel = new kVec(random(-1,1),random(-1,1),random(-1,1));    
   pos = kVec.clone(_pos);
   vec = kVec.clone(_vec);
   maxVel = _maxVel;
   maxForce = _maxForce;
   
   sepScale = 7;
   aliScale = 0.7;
   cohScale = 1;
   rangeOfVision = 70; 
   drawColor = 255;
 }
 
 // constructor complete
  kAgent(
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce,
     kVec _vel,
     float _sepScale,
     float _aliScale,
     float _cohScale,
     float _rangeOfVision){
   acc = new kVec(0,0,0);
   vel = kVec.clone(_vel);    
   pos = kVec.clone(_pos);
   vec = kVec.clone(_vec);
   maxVel = _maxVel;
   maxForce = _maxForce;
   sepScale = _sepScale;
   aliScale = _aliScale;
   cohScale = _cohScale;
   rangeOfVision = _rangeOfVision; 
   drawColor = 255;
 }
 
 
 // calculates new location
 void step(kWorld world){
   
    updatePop(world.population);
    vel.plus(acc);
    vel.limit(maxVel);  
    pos.plus(vel);
    acc = new kVec(0,0,0);  // reset acc to 0 each iteration
    borders(envSize);
    render();
 }
 
 int setMode(kVec maxForce) {
  if (maxForce < 0){
   return 1;
   }
  else if (maxForce > 1){
   return 3;
   }
  else {
   return 2;
  }

}
 void updatePop(ArrayList pop){
    
    // call population functions
    kVec sep = separate(pop);   
    kVec ali = align(pop);      
    kVec coh = cohesion(pop);   
    
    // weight vector
    sep.scale(sepScale);
    ali.scale(aliScale);
    coh.scale(cohScale);
    
    // add the vectors to acceleration
    acc.plus(sep);
    acc.plus(ali);
    acc.plus(coh);
    
  }    
 
 // steer
 kVec steer(kVec target, float threshold) {
    target.minus(pos); 
    float dist = target.length();

    if (dist > 0 && dist < threshold) {
      target.normalize();
      target.scale(maxVel);
      target.minus(vel); 
      target.limit(maxForce); 
    } else {
      target = new kVec(0,0,0);
    }
    return target;
  }

  // seek
  void seek(kVec target, float threshold) {
    acc.plus(steer(target, threshold));
  }
   
   
  // flee  
  void flee(kVec target, float threshold){
    acc.minus(steer(target, threshold));
  }   
  

  
  // wander - currently only working in 2d
  void wander() {
    // make this 3D
    float wanderR = 8;         
    float wanderD = 60;         
    float change = 0.1;
    wandertheta += random(-change,change);     

    kVec circleloc = kVec.clone(vel); 
    circleloc.normalize();            
    circleloc.scale(wanderD);          
    circleloc.plus(pos);              

    kVec circleOffSet = new kVec(wanderR*cos(wandertheta),wanderR*sin(wandertheta));
    circleOffSet.plus(circleloc);
    acc.plus(steer(circleOffSet, ht)); 
  }  

// separation
  kVec separate (ArrayList pop) {
    kVec sum = new kVec(0,0,0);
    int count = 0;

    for (int i = 0 ; i < pop.size(); i++) {
      kAgent other = (kAgent) pop.get(i);
      float dist = pos.distance(other.pos);
      
      if ((dist > 0) && (dist < rangeOfVision/1.5)) {
        kVec diff = kVec.clone(pos); 
        diff.minus(other.pos);
        diff.normalize();
        diff.scale(1/dist);          
        sum.plus(diff);
        count++;                     
      }
    }
    if (count > 0) {
      sum.scale(1/(float)count);
    }
    sumSep = kVec.clone(sum);
    return sum;
  }
 
  // alignment
  kVec align (ArrayList pop) {
    kVec sum = new kVec(0,0,0);
    int count = 0;
    for (int i = 0 ; i < pop.size(); i++) {
      kAgent other = (kAgent) pop.get(i);
      float dist = pos.distance(other.pos);
      if ((dist > 0) && (dist < rangeOfVision)) {
        sum.plus(other.vel);
        count++;
      }
    }
    if (count > 0) {
      sum.scale(1/(float)count);
      sum.limit(maxForce);
    }
    return sum;
  }

  // cohesion
  kVec cohesion (ArrayList pop) {
    kVec sum = new kVec(0,0,0);   
    int count = 0;
    for (int i = 0 ; i < pop.size(); i++) {
      kAgent other = (kAgent) pop.get(i);
      float dist = pos.distance(other.pos);
      if ((dist > 0) && (dist < rangeOfVision)) {
        sum.plus(other.pos); 
        count++;
      }
    }
    if (count > 0) {
      sum.scale(1/(float)count);
      return steer(sum, ht);
    }
    return sum;
  }

  void render() {

    // draw vectors  
    float vecDisScale = 2;
    
    kLine ln = new kLine(pos, vel, vel.length()*vecDisScale);
    ln.setColor(255,0,0);
    space.append(ln);

    kLine ln1 = new kLine(pos, sumSep, sumSep.length()*vecDisScale);
    ln1.setColor(0,0,255);
    //space.append(ln1);
    
    // draw agent
    kLine ln2 = new kLine(pos, vel, 3);
    ln2.setColor(drawColor);
    space.append(ln2);

  }

  void borders(float envSize) {
    if (pos.x < -envSize) pos.x = envSize;
    if (pos.y < -envSize) pos.y = envSize;
    if (pos.z < -envSize) pos.z = envSize;
    if (pos.x > envSize) pos.x = -envSize;
    if (pos.y > envSize) pos.y = -envSize;
    if (pos.z > envSize) pos.z = -envSize;
    
  }

}
class kAgentPredator extends kAgent{
   
 kAgentPredator(     
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce){
       
  super(
     _pos, 
     _vec, 
     _maxVel,
     _maxForce);
     
     drawColor = 0;
     agentType = "kAgentPredator";
  }
 
 
  void updatePop(ArrayList pop){  
    
   // seek pray
   // find closest agent
   float closestDist = envSize*envSize;
   int closestAgent = 0;
   for(int i = 0; i<pop.size(); i++){
     kAgent other = (kAgent) pop.get(i);
     if(other.agentType == "kAgentPrey"){
       float dist = pos.distance(other.pos);
       if(i > 0){
         if(dist < closestDist){
           closestDist = dist;
           closestAgent = i;
         }
           
       } else {
         closestDist = dist;
         closestAgent = 0;
       }
     }

   }
    
    // seek closest agent
    kAgent other = (kAgent) pop.get(closestAgent);
    kVec target = kVec.clone(other.pos);
    
    this.seek(target, 300);
  } 
 
 
   void render() {

    // draw vectors  
    float vecDisScale = 2;
    
    kLine ln = new kLine(pos, vel, vel.length()*vecDisScale);
    ln.setColor(255,0,0);
    space.append(ln);

    kLine ln1 = new kLine(pos, sumSep, sumSep.length()*vecDisScale);
    ln1.setColor(0,0,255);
    //space.append(ln1);
    
    // draw agent
    kLine ln2 = new kLine(pos, vel, 3);
    ln2.setColor(0);
    space.append(ln2);

  }
  
}
class kAgentPrey extends kAgent{
   
 kAgentPrey(     
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce){
       
  super(
     _pos, 
     _vec, 
     _maxVel,
     _maxForce);

     drawColor = 255;
     agentType = "kAgentPrey";
  }
 
  
   void updatePop(ArrayList pop){  
    
    kVec predFlee = this.preditorFlee(pop);
     
    // call population functions
    kVec sep = separate(pop);   
    kVec ali = align(pop);      
    kVec coh = cohesion(pop);   
    
    // weight vector
    sep.scale(sepScale);
    ali.scale(aliScale);
    coh.scale(cohScale);
    
    predFlee.scale(10);
    
    // add the vectors to acceleration
    acc.plus(sep);
    acc.plus(ali);
    acc.plus(coh);
    
    acc.minus(predFlee);
  } 
  
kVec preditorFlee(ArrayList pop){
  // find closest agent
  float closestDist = envSize*envSize;
  int closestAgent = 0;
  for(int i = 0; i<pop.size(); i++){
    kAgent other = (kAgent) pop.get(i);
    if(other.agentType == "kAgentPredator"){
      float dist = pos.distance(other.pos);

      if(i > 0){
        if(dist < closestDist){
          closestDist = dist;
          closestAgent = i;
        }
        
                  
      }else{
        closestDist = dist;
        closestAgent = 0;
      }
    }

  }
   
   // seek closest agent
   kAgent other = (kAgent) pop.get(closestAgent);
   float killDist =10; 
   if(closestDist < killDist){
      world1.deleteAgent(this);
      return new kVec(0,0,0);
    }else{
       kVec target = kVec.clone(other.pos);
       return this.steer(target, 100); 
    }
   
 
 }
   
}
class kAttractor{
 kVec pos;
 float magnatude;
 float attDisScale;
 float range;

//constructor - basic 
 kAttractor(kVec _pos){
   pos = kVec.clone(_pos);
   magnatude = -2;
   attDisScale = 10;
   range = 100;
 }

//constructor - complete 
 kAttractor(kVec _pos, float _magnatude, float _attDisScale, float _range){
   pos = kVec.clone(_pos);
   magnatude = _magnatude;
   attDisScale = _attDisScale;
   range = _range;
   
 }
 
 void render(){
  kLine ln0 = new kLine(pos.x, pos.y, pos.z - attDisScale, pos.x, pos.y, pos.z + attDisScale);  
  kLine ln1 = new kLine(pos.x, pos.y - attDisScale, pos.z, pos.x, pos.y + attDisScale, pos.z); 
  kLine ln2 = new kLine(pos.x - attDisScale, pos.y, pos.z, pos.x + attDisScale, pos.y, pos.z); 
  
  ln0.setColor(0,0,255);
  ln1.setColor(0,0,255);
  ln2.setColor(0,0,255);
  
  space.append(ln0);
  space.append(ln1);
  space.append(ln2);
   
 }
   
}

// a class which controls the agent population arraylist

class kWorld {
  ArrayList population;
  ArrayList attractors;
  
  kWorld() {
     population = new ArrayList();
     attractors = new ArrayList();
  }

  // cycles through each agent passing the population to it
  void run(){
    for (int i = 0; i < population.size(); i++) {
      kAgent a = (kAgent) population.get(i);  
      a.step(this); 
    }
    // attractors render loop
     for (int i = 0; i < attractors.size(); i++) {
      kAttractor a = (kAttractor) attractors.get(i);  
      a.render(); 
    }
    
  }


  // adds an agent to the population
  void addAgent(kAgent a) {
    population.add(a);
  }
  
  void addAttractor(kAttractor a) {
    attractors.add(a);
  }
  
  //kill
  void deleteAgent(kAgent a) {
   population.remove(a);
 }
  
}

Image:v12n3h.jpgImage:v12n3i.jpg Image:41f954fa9ce32-65-1.jpg Image:bat_form.jpg Image:bats_in_supercell.gif Image:batsCongress.jpg


Import Libraries

Declare variables

 gravity, wind_speed, wind_direction, bat_array[], vector_array[]

Declare Bat Class

BEGIN Set-up parameters

 Make parameters for world of bats

 For each bat in Bat Array

   Instantiate bat

END parameter setup

BEGIN Draw function

 Call bat class functions

END Draw function

BEGIN bat class

 Declare variables
  
 Declare Constructor

     kAgent constructor

 Methods for class

 Create update function which handles add and deletes

 Create searching function

   For each Frame execute

     For Each Bat in Bat Array

       Identify local swarm individuals and obstacles

       Identify Center of mass by segment for swarm

       Identify attractors such as prey

       Calculate distances from individuals to obstacles and prey

         if separation constraints are adequate, calculate vector opposite nearest neighbor

       Calculate azimuth to obstacle

       Calculate steering behaviors

       Calculate composite behavior

       Store composite behavior to Bat memory

 Create behavior function

   For Each Bat In Bat Array

     Vector turns based on stored composite behavior

     Move to next position

 Create display function

END bat class



Views
Personal tools