We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello!
I am brand new to processing - I have worked few a through tutorials and have only just started to write my own sketches.
I am trying to create a scenario where I have a number of objects moving towards the centre of the screen and turning more red as they do so. I am getting close to achieving this but find that the objects keep vibrating; I assume as the forces fight against each other.
But the reason I write this question is because I would also like to be able to click on an object and have it be removed from the screen. Allowing the objects to re-arrange themselves as they move towards the origin.
I have tried to start writing something like:
void mousePressed() {
removeball();
}
but so far I am not having much luck.
If anyone could have a look at the sketch below and provide some feedback it would be much appreciated.
WARNING: I have a feeling that what I written is terribly messy. My apologies
import toxi.geom.*;
ArrayList myballCollection;
float numberofballs = 14;
void setup() {
size(600, 600);
smooth();
myballCollection = new ArrayList();
for (int i = 0; i <numberofballs; i++) {
//float posx=200*sin(TWO_PI/numberofballs*i);
//float posy=200*cos(TWO_PI/numberofballs*i);
Vec3D original = new Vec3D(random(-width,width), random(-height,height), 0);
ball myball = new ball(original);
myballCollection.add(myball);
}
}
void draw() {
background(255);
translate (width/2, height/2);
line(0, 300, 0, -300);
line(300, 0, -300, 0);
for (int i = 0; i <myballCollection.size(); i++) {
ball myball_2 = (ball) myballCollection.get(i);
myball_2.run();
}
}
class ball {
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( 0, 0, 0);
float radius = 10;
int countCentrality =0;
float velMax= 1;
int countNeighbours=0;
int temperature= 40;
float cohMag=.00001;
float sepMag=2;
ball(Vec3D _loc) {
loc = _loc;
}
// functions
void run() {
display();
flock();
//warmUp();
movetoorigin();
update();
}
void mousePressed() {
removeball();
}
void removeball() {
for (int i=myballCollection.size()-1; i>=0; i--) {
ball other = (ball) myballCollection.get(i);
if (dist(mouseX, mouseY, other.loc.x, other.loc.y) < other.loc.z*0.5) {
myballCollection.remove(i);
}
}
}
void update() {
//flock();
println(countNeighbours);
if (countNeighbours==4) {
vel.clear();
acc.clear();
cohMag*=0.5;
sepMag*=0.5;
}
vel.addSelf(acc);
vel.limit(velMax);
loc.addSelf(vel);
acc = new Vec3D();
}
// void warmUp(float magnitude) {
// if (countNeighbours>0)temperature+=countNeighbours;
//
//
//
//
// }
void movetoorigin() {
Vec3D diff = target.sub(loc);
float distance = diff.magnitude();
diff.normalize();
diff.scaleSelf(distance/80);
if (countNeighbours<3) {
acc.addSelf(diff);
}
}
void display() {
// warmUp();
//float colour=(loc.x+loc.y)*10;
// float redx = loc.x;
// if (redx<0) {
// redx = redx*-1;
// }
// float redy = loc.y;
// if (redy<0) {
// redy = redy*-1;
// }
float dist = target.distanceTo(loc);
float red = map(dist, 0, 100, 255, 0);
fill(red+50, 0, 0);
ellipse(loc.x, loc.y, radius*2, radius*2);
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 < myballCollection.size();i++) {
ball other = (ball) myballCollection.get(i);
float distance = loc.distanceTo(other.loc);
if (distance > 0 && distance < 40) {
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 < myballCollection.size();i++) {
ball other = (ball) myballCollection.get(i);
float distance = loc.distanceTo(other.loc);
if (distance > radius*2 && distance < 60) {
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 < myballCollection.size();i++) {
ball other = (ball) myballCollection.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);
}
}
Answers
you can't just add mousePressed() to any class and expect it to run. it's only defined at the top level, same level as setup() and draw().
but you can move it there and inside it iterate over the balls and remove the one that matches (pretty much your removeBall code)
Thanks for your reply koogs. I'm sure you can see from my sketch that I still have a lot to learn.
I've tried moving mousePressed() to the top level but I'm still not seeing the desired results.
I now have (a slightly cleaner) sketch that looks like this:
Any ideas would be much appreciated.
Transformations like translate(), rotate(), etc don't affect mouseX & mouseY! :o3
Thank you!
I ditched the translate() and tweaked a little bit and its now getting close to what I was hoping for.
Thanks to GoToLoop and Koogs