I have been working on making a Physics Engine and came across a problem when handling circle collisions. The program seems to resolve collisions just fine in most instances. However at lower speeds the circles begin to overlapp one another.
To illustrate the problem I have made the following gif file. I ahve also added gravitational attraction between the objects as it helps to illustrate the problem better.
I will post the relevnant code below. The class definition of the object that represents the circles withouth most of the methods:
class Mover {
PVector pos;
PVector vel;
PVector acc;
float ang = 0;
float angVel = 0;
float angAcc = 0;
float mass;
float getRadius() {
return mass/10;
}
void update() {
vel.add(acc);
pos.add(vel);
acc.mult(0);
angVel += angAcc;
ang += angVel;
angAcc = 0;
}
}
The code that checks for collsions:
boolean checkCollision(Mover m) {
float d = pos.dist(m.pos);
float dvel = vel.dist(m.vel);
PVector pos21 = m.pos.copy().sub(pos);
PVector vel21 = m.vel.copy().sub(vel);
if(d < getRadius() + m.getRadius() + dvel && vel21.dot(pos21) < 0) return true;
return false;
}
And finally outside this class the objects are handled with an ArrayList and this is the code that resolves collisions:
void applyCollisions() {
for(int i = 0; i < movers.size(); i++) {
for(int j = i + 1; j < movers.size(); j++) {
Mover mi = movers.get(i);
Mover mj = movers.get(j);
if(mi.checkCollision(mj)) {
PVector v1 = mi.vel.copy();
PVector v2 = mj.vel.copy();
PVector x1 = mi.pos.copy();
PVector x2 = mj.pos.copy();
PVector x12 = x1.copy().sub(x2);
PVector v12 = v1.copy().sub(v2);
PVector x21 = x2.copy().sub(x1);
PVector v21 = v2.copy().sub(v1);
float m1 = mi.mass, m2 = mj.mass;
mi.angVel = mi.calcAngVel(x12.normalize().mult(mi.getRadius()));
mj.angVel = mj.calcAngVel(x21.normalize().mult(mi.getRadius()));
mi.vel.sub(x12.mult((2*m2/(m1 + m2))*(v12.dot(x12)/x12.magSq())));
mj.vel.sub(x21.mult((2*m1/(m1 + m2))*(v21.dot(x21)/x21.magSq())));
}
}
}
}
The collision resolution is based on the following formula found on Wikipedia.