Problem with elastic collision

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;
    }
  }

}
Sign In or Register to comment.