The code used for this example is based on the structure used by Kokkugia (www.kokkugia.com) for it's agent based work. The fall off and range structure is based on Ian Couzin's work (http://icouzin.princeton.edu/) as outlined by Robert Hodgins for a Cinder tutorial on flocking (http://libcinder.org/docs/v0.8.3/hello_cinder.html).
Tab 1(flock):
- int agentCount = 1000;
- ArrayList agents;
- void setup(){
- smooth();
- size(1280,720);
- agents = new ArrayList();
- for(int i = 0; i < agentCount; i++){
- PVector startPos = new PVector(random(0,width), random(0,height));
- PVector startVel = new PVector(random(-1, 1), random(-1,1));
- startVel.normalize();
- float startRad = random(2,10);
- agent a = new agent(startPos, startVel, startRad);
- agents.add(a);
- }
- }
- void draw(){
- background(255);
- for(int i = 0; i < agents.size(); i++){
- agent a = (agent) agents.get(i);
- a.update();
- //a.render();
- }
- for(int i = 0; i < agents.size(); i++){
- agent a = (agent) agents.get(i);
- // a.update();
- a.render();
- }
- for(int i = 0; i< agents.size(); i++){
- agent a = (agent) agents.get(i);
- // a.update();
- a.renderE();
- }
- saveFrame();
- if(frameCount > 1000){
- exit();
- }
- }
Tab 2: agents
- class agent{
- float rad;
- PVector pos;
- PVector vel;
- float range;
- float lowThresh;
- float highThresh;
- agent(PVector _pos, PVector _vel, float _rad){
- rad = _rad;
- pos = _pos;
- vel = _vel;
- //set values for range here. range is overall distance, and the thresh variables say what percent
- //of that range we cut off for the different functions.
- range = 60;
- lowThresh = .40;
- highThresh = .60;
- }
- void update(){
- PVector acc = new PVector();
- //vel = new PVector();
- PVector coh = cohesion();
- PVector avd = avoid();
- PVector ali = align();
- //adjust the strengths of the behaviors here
- coh.mult(.3);
- avd.mult(1);
- ali.mult(1);
- acc.add(coh);
- acc.add(avd);
- acc.add(ali);
- vel.add(acc);
- vel.limit(2);
- pos.add(vel);
- borders();
- }
- void borders(){
- if(pos.x < 0){
- pos.x = width;
- }
- if(pos.y < 0){
- pos.y = height;
- }
- if(pos.x > width){
- pos.x = 0;
- }
- if(pos.y > height){
- pos.y = 0;
- }
- }
- PVector align(){
- PVector sum = new PVector();
- float threshDelta = highThresh - lowThresh;
- for(int i = 0; i < agents.size(); i++){
- agent other = (agent) agents.get(i);
- float dis = pos.dist(other.pos);
- float percent = pow(dis,2)/pow(range,2);
- if(percent < highThresh && dis > lowThresh){
- percent = (percent - lowThresh)/threshDelta;
- float scalar = (.5-cos(percent*2*PI)*.5 + .5) *.1;
- PVector temp = other.vel.get();
- temp.normalize();
- temp.mult(scalar);
- sum.add(temp);
- }
- }
- return sum;
- }
- //this makes agents avoid each other
- PVector avoid(){
- PVector sum = new PVector();
- for(int i = 0; i < agents.size(); i++){
- agent other = (agent) agents.get(i);
- float dis = pos.dist(other.pos);
- dis = pow(dis,2);
- float percent = dis/pow(range,2);
- if(dis >0 && percent < lowThresh){
- float scalar = (lowThresh/ percent - 1)*.01;
- PVector temp = pos.get();
- temp.sub(other.pos);
- temp.normalize();
- temp.mult(scalar);
- sum.add(temp);
- }
- }
- return sum;
- }
- PVector cohesion(){
- PVector sum = new PVector();
- float threshDelta = 1-highThresh;
- for(int i = 0; i < agents.size(); i++){
- agent other = (agent) agents.get(i);
- float dis = pos.dist(other.pos);
- float percent = pow(dis,2)/( pow(range,2));
- if(percent > highThresh && percent <= 1){
- percent = (percent - highThresh)/threshDelta;
- float scalar = (.5- cos(percent*PI*2)*.5 +.5)*.01;
- PVector temp = other.pos.get();
- temp.sub(pos);
- temp.normalize();
- temp.mult(scalar);
- sum.add(temp);
- }
- }
- return sum;
- }
- void render(){
- float closeDist = 99999;
- strokeWeight(.01);
- stroke(150);
- PVector target = new PVector();
- for(int i = 0; i < agents.size(); i++){
- agent other = (agent) agents.get(i);
- float tempDist = pos.dist(other.pos);
- if(tempDist < .5*range && tempDist > 0){
- line(pos.x, pos.y, other.pos.x, other.pos.y);
- }
- }
- }
- void renderE(){
- fill(0, 0,0);
- // stroke(150,0,0);
- noStroke();
- ellipse(pos.x, pos.y, rad, rad);
- }
- }
No comments:
Post a Comment