We are about to switch to a new forum software. Until then we have removed the registration on this forum.
A few days ago I asked a question on removing objects on mouse click (http://forum.processing.org/two/discussion/981/remove-object-on-mouse-click#Item_5) that was kindly answered.
I have started to get my sketch to where I wish -- but I still need to iron out some of the bugs. I have included a hand drawn sketch that I hope illustrates what I am trying to achieve.
My objects keep vibrating - I believe as the flock forces are fighting against each other. I have tried to decelerate them as they approach neighbours but I'm still having trouble.
My code is below:
import toxi.geom.*;
ArrayList mypenguinCollection;
float numberofpenguins = 15;
float distanceformouse = 1;
void setup() {
size(600, 600);
smooth();
mypenguinCollection = new ArrayList();
for (int i = 0; i <numberofpenguins; i++) {
float posx=200*sin(TWO_PI/10*i);
float posy=200*cos(TWO_PI/10*i);
Vec3D original = new Vec3D(random(100, 500), random(100, 500), 0);
penguin mypenguin = new penguin(original);
mypenguinCollection.add(mypenguin);
}
}
void draw() {
background(255);
line(300, 0, 300, 600);
line(0, 300, 600, 300);
for (int i = 0; i <mypenguinCollection.size(); i++) {
penguin mypenguin_2 = (penguin) mypenguinCollection.get(i);
mypenguin_2.run();
}
}
class penguin {
Vec3D loc = new Vec3D (0, 0, 0);
Vec3D speed = new Vec3D (10000, 0, 0);
Vec3D gravity = new Vec3D (0, 0.2, 0);
Vec3D acc= new Vec3D(0, 0, 0);
Vec3D vel = new Vec3D(0, 0, 0);
Vec3D target = new Vec3D( 300, 300, 0);
float radius = 10;
int countCentrality =0;
float velMax= .8;
int countNeighbours=0;
int temperature= 40;
float cohMag=.000001;
float sepMag=2;
penguin(Vec3D _loc) {
loc = _loc;
}
void run() {
display();
flock();
movetoorigin();
update();
}
void update() {
println(countNeighbours);
if (countNeighbours==3) {
vel.clear();
acc.clear();
cohMag*=0.8;
sepMag*=1.0;
}
vel.addSelf(acc);
vel.limit(velMax);
loc.addSelf(vel);
acc = new Vec3D();
}
void movetoorigin() {
Vec3D diff = target.sub(loc);
float distance = diff.magnitude();
diff.normalize();
diff.scaleSelf(distance/5);
if (countNeighbours<5) {
acc.addSelf(diff);
}
}
void display() {
float dist = target.distanceTo(loc);
float red = map(dist, 0, 100, 255, 0);
fill(red+5, 0, 255-red);
ellipse(loc.x, loc.y, radius*1.2, radius*1.1);
//ellipse(loc.x, loc.y, 10, 10);
}
void move() {
speed.addSelf(acc);
speed.limit(1);
loc.addSelf(speed);
acc.clear();
}
void flock() {
separate(sepMag);
cohesion(cohMag);
//align(0.00001);
}
void align(float magnitude) {
Vec3D steer = new Vec3D();
int count = 0;
for (int i=0; i < mypenguinCollection.size();i++) {
penguin other = (penguin) mypenguinCollection.get(i);
float distance = loc.distanceTo(other.loc);
if (distance > 0 && distance < 50) {
steer.addSelf(other.speed);
count++;
}
}
if (count > 0) {
steer.scaleSelf(1.0/count);
}
steer.scaleSelf(magnitude);
acc.addSelf(steer);
}
void cohesion(float magnitude) {
countNeighbours=0;
Vec3D sum = new Vec3D();
int count = 0;
for (int i=0; i < mypenguinCollection.size();i++) {
penguin other = (penguin) mypenguinCollection.get(i);
float distance = loc.distanceTo(other.loc);
if (distance > radius*2.5 && distance < 40) {
sum.addSelf(other.loc);
count++;
}
if (distance > radius*2.5 && distance < 40) {
sum.addSelf(other.loc);
count++;
}
if (distance > radius*2.5 && distance < 40) {
sum.addSelf(other.loc);
count++;
}
if (distance>0&&distance<(radius*2+8)) {
countNeighbours++;
}
}
if (count > 0) {
sum.scaleSelf(1.0/count);
}
Vec3D steer = sum.sub(loc);
steer.scaleSelf(magnitude);
acc.addSelf(steer);
}
void separate(float magnitude) {
Vec3D steer = new Vec3D();
int count = 0;
for (int i=0; i < mypenguinCollection.size();i++) {
penguin other = (penguin) mypenguinCollection.get(i);
float distance = loc.distanceTo(other.loc);
if (distance>0 && distance<radius*2) {
Vec3D diff = loc.sub(other.loc);
diff.normalizeTo(distance);
steer.addSelf(diff);
count++;
}
}
if (count > 0) {
steer.scaleSelf(1.0/count);
}
steer.scaleSelf(magnitude);
acc.addSelf(steer);
}
}
//boolean seperate =
Vec3D loc = new Vec3D (0, 0, 0);
Vec3D speed = new Vec3D (10000, 0, 0);
Vec3D gravity = new Vec3D (0, 0.2, 0);
Vec3D acc= new Vec3D(0, 0, 0);
Vec3D vel = new Vec3D(0, 0, 0);
Vec3D target = new Vec3D( 300, 300, 0);
float radius = 10;
int countCentrality =0;
float velMax= .8;
int countNeighbours=0;
int temperature= 40;
float cohMag=.000001;
float sepMag=2;
void mousePressed() {
if (mouseButton == LEFT) {
for (int i=mypenguinCollection.size()-1; i>=0; i--) {
penguin other = (penguin) mypenguinCollection.get(i);
if (dist(mouseX, mouseY, other.loc.x, other.loc.y) < 7.5) {
// mypenguinCollection.remove(i);
other.target= new Vec3D(random(75, 115), random(75, 115), 0);
float distance= other.loc.distanceTo(other.target);
other.velMax=map(distance, 0, width, 0, 5);
other.cohMag=other.cohMag*-1;
other.sepMag=0;
}
}
}
else if (mouseButton == RIGHT) {
for (int i=mypenguinCollection.size()-1; i>=0; i--) {
penguin other = (penguin) mypenguinCollection.get(i);
if (dist(mouseX, mouseY, other.loc.x, other.loc.y) < 7.5) {
// mypenguinCollection.remove(i);
other.target= new Vec3D(300, 300, 0);
float distance= other.loc.distanceTo(other.target);
other.velMax=map(distance, 0, width, 0, 5);
//vel.clear();
//acc.clear();
other.cohMag=other.cohMag*0.1;
other.sepMag=1;
}
}
}
}