We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello, I'm trying to get two or more objects in the screen to move towards the mouse cursor when the mouse is pressed. The tricky part is, they can't overlap each other, so I am trying to get some physics to work. I used hit detection and elastic collision formula to get them to react to one another, and it kind of works, but when they get as close as they can to the cursor, things get a bit jumpy. I think the problem is each one's acceleration pushes against the rest, who in turn accelerate , who eventually results in all objects going berserk. Any ideas on how I can get all objects to just stop when they are as close as they can to the cursor without overlapping?
Here's my code, first the main sketch:
ArrayList<Person> crowd = new ArrayList<Person>();
int amount = 2;
void setup(){
size(600, 400);
background(255);
for(int i = 0; i < amount; i++){
float x = random(width-100)+50;
float y = random(height-100)+50;
PVector location = new PVector(x,y);
crowd.add(new Person(location, 16, 16));
}
}
void draw(){
background(255);
for(Person p : crowd){
for(Person q : crowd){
if(p != q)
p.hitTest(q);
}
p.show();
}
}
And here's the class
class Person{
PVector location = new PVector(0,0),
speed = new PVector(0,0),
newSpeed = new PVector(0,0),
oldSpeed = new PVector(0,0);
int r, mass, start, duration;
float xdistance, ydistance, xspeed, yspeed, rand;
boolean hit = false;
Person(PVector location_, int r_, int mass_){
location = location_;
r = r_;
mass = mass_;
rand = random(5);
}
void show(){
if(r > 0){
pushMatrix();
beginShape();
if(hit)
fill(125);
else
fill(0);
noStroke();
translate(location.x, location.y);
ellipse(0,0,r,r);
popMatrix();
}
if(mousePressed){
duration = millis() - start;
xdistance = mouseX - location.x;
ydistance = mouseY - location.y;
xspeed = round(rand * (xdistance/10000 * duration));
yspeed = round(rand * (ydistance/10000 * duration));
speed = new PVector(xspeed, yspeed);
if(hit)
speed.add(newSpeed);
location.add(speed);
}else{
start = millis();
newSpeed.mult(-1);
}
}
void hitTest(Person person) {
float rad = (r > person.r ? r : person.r);
if (dist(location.x, location.y, person.location.x, person.location.y) <= rad+10) {
person.hit = true;
hit = true;
float newVelX1 = (xspeed * (mass - person.mass) + (2 * person.mass * person.xspeed)) / (mass + person.mass);
float newVelY1 = (yspeed * (mass - person.mass) + (2 * person.mass * person.yspeed)) / (mass + person.mass);
float newVelX2 = (person.xspeed * (person.mass - mass) + (2 * mass * xspeed)) / (mass + person.mass);
float newVelY2 = (person.yspeed * (person.mass - mass) + (2 * mass * yspeed)) / (mass + person.mass);
newSpeed = new PVector(newVelX1, newVelY1);
person.newSpeed = new PVector(newVelX2, newVelY2);
} else {
person.hit = false;
hit = false;
}
}
}