Hi, I have got these two problems:
1st: I would like to have the agents in a randomized size pattern
2nd: I would like to create lines between any of the agents from group 1 and any of the agents from group 2 if the distance between them was less than something.
In the code posted below, there is no such thing as having them loop around each other. They're just looping around themselves.
I would appreciate it if you let me know about it
// imports the toxic library core
import toxi.geom.*;
ArrayList agentPop1;
ArrayList agentPop2;
void setup(){
size(500,500);
smooth();
agentPop1 = new ArrayList();
agentPop2 = new ArrayList();
for(int i = 0; i < 100; i++ ){
// make new variables for the agent
Vec3D pos = new Vec3D(random(0,width),random(0,height),0);
Vec3D vel = new Vec3D(random(-1,1),random(-1,1),0);
float r = random(25,35);
float mV = random(2,4);
float mF = random(0.1, 0.2);
// call agent constructor
agentPop1.add(new agent(pos, vel, r, mV, mF, 1));
}
for(int i = 0; i < 100; i++ ){
// make new variables for the agent
Vec3D pos = new Vec3D(random(0,width),random(0,height),0);
Vec3D vel = new Vec3D(random(-1,1),random(-1,1),0);
float r = random(1 - 20);
float mV = random(2,4);
float mF = random(0.1, 0.2);
// call agent constructor
agentPop2.add(new agent(pos, vel, r, mV, mF, 0));
}
}
void draw(){
background(0);
for(int i = 0; i < agentPop1.size(); i++){
agent a = (agent) agentPop1.get(i);
a.render();
a.update();
}
for(int i = 0; i < agentPop2.size(); i++){
agent a = (agent) agentPop2.get(i);
a.render();
a.update();
}
}
class agent{
// states
Vec3D pos;
Vec3D vel;
float rangeOfVis;
float maxVel;
float maxForce;
int agentType;
// constructor
agent(Vec3D _pos, Vec3D _vel, float _rangeOfVis, float _maxVel, float _maxForce, int _agentType){
pos = _pos;
vel = _vel;
rangeOfVis = _rangeOfVis;
maxVel = _maxVel;
maxForce = _maxForce;
agentType = _agentType;
}
// behaviors
//rangeOfVis=5
//draw line from one agent of the 1st list to another agent of the 2nd list
void linear(int rangeOfVis){
// loop through each agentPop1
for (int i = 0; i < agentPop1.size(); i++){
agentPop1 other = (agentPop1)agentPop1.get(i);
// get distance
float distance = pos.distance(other.pos);
// is this distance less than the range of vision
if( (distance < rangeOfVis) && (distance > 0) ){
// draw a line
agentPop1.line(this);
}
void update(){
// set acc to 0
Vec3D acc = new Vec3D();
if(agentType == 1){
// call vector behaviors
Vec3D seek = steer( new Vec3D(mouseX, mouseY, 0) );
Vec3D ali = alignment(agentPop1, rangeOfVis);
Vec3D coh = cohesion(agentPop1, rangeOfVis);
Vec3D sep = separation(agentPop1, rangeOfVis/3);
// scale the vectors
seek.scaleSelf(0);
ali.scaleSelf(5);
coh.scaleSelf(2);
sep.scaleSelf(5);
// add vectors to acc
acc.addSelf(seek);
acc.addSelf(ali);
acc.addSelf(coh);
acc.addSelf(sep);
}else{
// call vector behaviors
Vec3D seek = steer( new Vec3D(mouseX, mouseY, 0) );
Vec3D ali = alignment(agentPop2, rangeOfVis);
Vec3D coh = cohesion(agentPop2, rangeOfVis);
Vec3D sep = separation(agentPop2, rangeOfVis/3);
// scale the vectors
seek.scaleSelf(0);
ali.scaleSelf(5);
coh.scaleSelf(2);
sep.scaleSelf(5);
// add vectors to acc
acc.addSelf(seek);
acc.addSelf(ali);
acc.addSelf(coh);
acc.addSelf(sep);
}
// add acc to current vel vel = vel + acc
vel.addSelf(acc);
// limit vel - maxVel
vel.limit(maxVel);
// pos = pos + vel
pos.addSelf(vel);
borders();
}
Vec3D steer(Vec3D target){
Vec3D st;
// target - pos = vector between agent and target
target.subSelf(pos);
// how far away is the target
float d = target.magnitude();
// if not yet at target
if(d > 0){
// set mag to 1
target.normalize();
// scale by maxVel
target.scaleSelf(maxVel);
// subtract vel
target.subSelf(vel);
// clone to break reference
st = target.copy();
// limit to maxForce - limit turning ability
st.limit(maxForce);
}
else{
// if at target already then set st to 0
st = new Vec3D();
}
return st;
}
Vec3D separation(ArrayList pop, float localRangeOfVis){
// sum and count
Vec3D sum = new Vec3D();
int count = 0;
// loop through all the agents
for(int i = 0; i < pop.size(); i++){
// getting an agent out of the arraylist
agent a = (agent) pop.get(i);
// distance to agent
float d = pos.distanceTo(a.pos);
// if in range of vis
if( (d < localRangeOfVis) && (d > 0) ){
// make vec between other agent and this agent
Vec3D vec = pos.sub(a.pos);
// scale 1/d
vec.scaleSelf(1/d);
// sum vectors: sum = sum + vec
sum.addSelf(vec);
count++;
}
}
if(count > 0){
// divide sum by count (average) sum = sum x 1/count or sum = sum / count
sum.scaleSelf(1/(float)count);
// limit to maxForce
sum.limit(maxForce);
}
// return sum
return sum;
}
Vec3D cohesion(ArrayList pop, float localRangeOfVis){
// sum vector and count
Vec3D sum = new Vec3D(); //(0,0,0)
int count = 0;
//loop through all of the agents
for(int i = 0; i < pop.size(); i++){
// get one agent out
agent a = (agent) pop.get(i);
// get distance to other agent
float d = pos.distanceTo(a.pos);
// if within range of vision
if( (d < localRangeOfVis) && (d > 0) ){
// sum = sum + a.pos
sum.addSelf(a.pos);
// count = count + 1
count++;
}
} //end loop
Vec3D result;
// find average pos - divide sum by the count
if(count > 0){
sum.scaleSelf(1/(float)count);
// call the steer function - pass the sum as the target
result = steer(sum);
}else{
result = new Vec3D();
}
// return the result of the steer function
return result;
}
Vec3D alignment(ArrayList pop, float localRangeOfVis){
// set a 0 sum vector + set a counter
Vec3D sum = new Vec3D();
int count = 0;
// loop through the population of agents
for(int i = 0; i < pop.size(); i++){
// get one agent out at a time
agent a = (agent) pop.get(i);
// check if it is in the rangeOfVis
float d = pos.distanceTo(a.pos);
if( (d < localRangeOfVis) && (d > 0) ){
// add its vel to sum
sum.addSelf(a.vel);
count++;
}
}
// if count > 0 then divide sum by the count
if(count > 0){
sum.scaleSelf(1/(float)count);
// limit the sum vector - by maxForce
sum.limit(maxForce);
}
// return the sum
return sum;
}
void borders(){
if(pos.x > width) pos.x = 0;
if(pos.y > height) pos.y = 0;
if(pos.x < 0) pos.x = width;
if(pos.y < 0) pos.y = height;
}
void render(){
if(agentType == 1){
fill(255);
ellipse(pos.x, pos.y, 8, 8);
}else{
fill(100);
ellipse(pos.x, pos.y, 8, 8);
}
}
}