fullscreen
Predator.pdePrey.pdePreyPredator3D.pdevAgent.pdevWorld.pde
class vAgentPredator extends vAgent{
vAgentPredator(
Vec3D _pos,
Vec3D _vec,
float _maxVel,
float _maxForce){
super(
_pos,
_vec,
_maxVel,
_maxForce);
drawColor = 0;
agentType = "vAgentPredator";
vel = new Vec3D(0,0,0);
}
void step(vWorld world){
updatePop(world.population);
vel.addSelf(acc);
vel.limit(maxVel);
pos.addSelf(vel);
acc = new Vec3D(0,0,0); // reset acc to 0 each iteration
borders(envSize);
render();
}
void updatePop(ArrayList pop){
// seek pray
// find closest agent
float closestDist = envSize*envSize;
int closestAgent = 0;
for(int i = 0; i<pop.size(); i++){
vAgent other = (vAgent) pop.get(i);
if(other.agentType == "vAgentPrey"){
float dist = pos.distanceTo(other.pos);
if(i > 0){
if(dist < closestDist){
closestDist = dist;
closestAgent = i;
}
}else{
closestDist = dist;
closestAgent = 0;
}
}
}
// seek closest agent
vAgent other = (vAgent) pop.get(closestAgent);
Vec3D target = other.pos.copy();
this.seek(target, 300);
}
void render() {
strokeWeight(2);
stroke(0);
Line3D l = new Line3D(pos,pos.add(vel.normalize().scale(10)));
gfx.line(l);
stroke(255,0,0);
point(pos.x,pos.y,pos.z);
}
}
class vAgentPrey extends vAgent{
vAgentPrey(
Vec3D _pos,
Vec3D _vec,
float _maxVel,
float _maxForce){
super(
_pos,
_vec,
_maxVel,
_maxForce);
drawColor = 255;
agentType = "vAgentPrey";
}
void updatePop(ArrayList pop){
Vec3D predFlee = this.preditorFlee(pop);
// call population functions
Vec3D sep = separate(pop);
Vec3D ali = align(pop);
Vec3D coh = cohesion(pop);
// weight vector
sep.scaleSelf(sepScale);
ali.scaleSelf(aliScale);
coh.scaleSelf(cohScale);
predFlee.scaleSelf(10);
// add the vectors to acceleration
acc.addSelf(sep);
acc.addSelf(ali);
acc.addSelf(coh);
acc.subSelf(predFlee);
}
Vec3D preditorFlee(ArrayList pop){
// find closest agent
float closestDist = envSize*envSize;
int closestAgent = 0;
for(int i = 0; i<pop.size(); i++){
vAgent other = (vAgent) pop.get(i);
if(other.agentType == "vAgentPredator"){
float dist = pos.distanceTo(other.pos);
if(i > 0){
if(dist < closestDist){
closestDist = dist;
closestAgent = i;
}
}else{
closestDist = dist;
closestAgent = 0;
}
}
}
// seek closest agent
vAgent other = (vAgent) pop.get(closestAgent);
Vec3D target = other.pos.copy();
return this.steer(target, 100);
}
}
import peasy.*;
import toxi.processing.*;
import toxi.geom.*;
PeasyCam cam;
vWorld world1;
ToxiclibsSupport gfx;
float envSize = 300;
void setup(){
size(500,500,P3D);
cam = new PeasyCam(this, 1100);
cam.setMinimumDistance(800);
cam.setMaximumDistance(1400);
gfx=new ToxiclibsSupport(this);
world1 = new vWorld();
// create agents
for (int i = 0; i < 200; i++) {
world1.addAgent(new vAgentPrey(new Vec3D(random(-250,250),random(-250,250),random(-250,250)), new Vec3D(random(-1,1),random(-1,1),random(-1,1)), 10, 0.1));
}
for (int i = 0; i < 10; i++) {
world1.addAgent(new vAgentPredator(new Vec3D(random(-250,250),random(-250,250),random(-250,250)),new Vec3D(random(-1,1),random(-1,1),random(-1,1)), 12, 1));
}
}
void draw(){
background(120);
world1.addBox(envSize);
world1.run();
}
// simple 3D agent class - based on code from dan shiffman
// roland snooks | kokkugia.com | 2007
class vAgent{
Vec3D acc;
Vec3D vel;
Vec3D pos;
Vec3D vec;
float maxVel;
float maxForce;
float sepScale;
float aliScale;
float cohScale;
float rangeOfVision;
float wandertheta;
float wanderomega;
float attOffset = 200;
float ht = envSize*2;
int drawColor;
String agentType = "vAgent";
Vec3D sumSep = new Vec3D(0,0,0);
// constructor simple
vAgent(
Vec3D _pos,
Vec3D _vec,
float _maxVel,
float _maxForce){
acc = new Vec3D(0,0,0);
vel = new Vec3D(random(-1,1),random(-1,1),random(-1,1));
pos = _pos.copy();
vec = _vec.copy();
maxVel = _maxVel;
maxForce = _maxForce;
sepScale = 7;
aliScale = 0.7;
cohScale = 1;
rangeOfVision = 70;
drawColor = 255;
}
// constructor complete
vAgent(
Vec3D _pos,
Vec3D _vec,
float _maxVel,
float _maxForce,
Vec3D _vel,
float _sepScale,
float _aliScale,
float _cohScale,
float _rangeOfVision){
acc = new Vec3D(0,0,0);
vel = _vel.copy();
pos = _pos.copy();
vec = _vec.copy();
maxVel = _maxVel;
maxForce = _maxForce;
sepScale = _sepScale;
aliScale = _aliScale;
cohScale = _cohScale;
rangeOfVision = _rangeOfVision;
drawColor = 255;
}
// calculates new location
void step(vWorld world){
updatePop(world.population);
vel.addSelf(acc);
vel.limit(maxVel);
pos.addSelf(vel);
acc = new Vec3D(0,0,0); // reset acc to 0 each iteration
borders(envSize);
render();
}
void updatePop(ArrayList pop){
// call population functions
Vec3D sep = separate(pop);
Vec3D ali = align(pop);
Vec3D coh = cohesion(pop);
// weight vector
sep.scaleSelf(sepScale);
ali.scaleSelf(aliScale);
coh.scaleSelf(cohScale);
// add the vectors to acceleration
acc.addSelf(sep);
acc.addSelf(ali);
acc.addSelf(coh);
}
// steer
Vec3D steer(Vec3D target, float threshold) {
target.subSelf(pos);
float dist = target.magnitude();
if (dist > 0 && dist < threshold) {
target.normalize();
target.scaleSelf(maxVel);
target.subSelf(vel);
target.limit(maxForce);
}
else {
target = new Vec3D(0,0,0);
}
return target;
}
// seek
void seek(Vec3D target, float threshold) {
acc.addSelf(steer(target, threshold));
}
// flee
void flee(Vec3D target, float threshold){
acc.subSelf(steer(target, threshold));
}
// wander
void wander() {
float wanderR =8;
float wanderD = 60;
float change = 0.1;
wandertheta += random(-change,change);
wanderomega += random(-change,change);
Vec3D circleloc = vel.copy();
circleloc.normalize();
circleloc.scaleSelf(wanderD);
circleloc.addSelf(pos);
//Vec3D circleOffSet = new Vec3D(wanderR*cos(wandertheta),wanderR*sin(wandertheta),0);
Vec3D circleOffSet = new Vec3D(wanderR*sin(wandertheta)*cos(wanderomega),wanderR*sin(wandertheta)*sin(wanderomega),wanderR*cos(wandertheta));
circleOffSet.addSelf(circleloc);
acc.addSelf(steer(circleOffSet,ht));
}
// separation
Vec3D separate (ArrayList pop) {
Vec3D sum = new Vec3D(0,0,0);
int count = 0;
for (int i = 0 ; i < pop.size(); i++) {
vAgent other = (vAgent) pop.get(i);
float dist = pos.distanceTo(other.pos);
if ((dist > 0) && (dist < rangeOfVision/1.5)) {
Vec3D diff = pos.copy();
diff.subSelf(other.pos);
diff.normalize();
diff.scaleSelf(1/dist);
sum.addSelf(diff);
count++;
}
}
if (count > 0) {
sum.scaleSelf(1/(float)count);
}
sumSep = sum.copy();
return sum;
}
// alignment
Vec3D align (ArrayList pop) {
Vec3D sum = new Vec3D(0,0,0);
int count = 0;
for (int i = 0 ; i < pop.size(); i++) {
vAgent other = (vAgent) pop.get(i);
float dist = pos.distanceTo(other.pos);
if ((dist > 0) && (dist < rangeOfVision)) {
sum.addSelf(other.vel);
count++;
}
}
if (count > 0) {
sum.scaleSelf(1/(float)count);
sum.limit(maxForce);
}
return sum;
}
// cohesion
Vec3D cohesion (ArrayList pop) {
Vec3D sum = new Vec3D(0,0,0);
int count = 0;
for (int i = 0 ; i < pop.size(); i++) {
vAgent other = (vAgent) pop.get(i);
float dist = pos.distanceTo(other.pos);
if ((dist > 0) && (dist < rangeOfVision)) {
sum.addSelf(other.pos);
count++;
}
}
if (count > 0) {
sum.scaleSelf(1/(float)count);
return steer(sum, ht);
}
return sum;
}
void render() {
strokeWeight(1);
stroke(255);
Line3D l = new Line3D(pos,pos.add(vel.normalize().scale(8)));
gfx.line(l);
stroke(255);
point(pos.x,pos.y,pos.z);
}
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 vWorld {
ArrayList population;
vWorld() {
population = new ArrayList();
}
// cycles through each agent passing the population to it
void run(){
for (int i = 0; i < population.size(); i++) {
vAgent a = (vAgent) population.get(i);
a.step(this);
}
}
// adds an agent to the population
void addAgent(vAgent a) {
population.add(a);
}
void addBox(float env){
noFill();
stroke(0);
strokeWeight(1);
box(env*2);
}
}