Original Post
Today i sat down in wrote me a function which checks if 2 moving Spheres collide or not because I need this for my Game projekt. And I wondered if there are any improvments performance wise which can be done. Ps: I tested it a bit but would be glad if any bugs can be found
public boolean checkCollision(Sphere s1, Sphere s2){
// s2 position relativ to s1
Vec3f pos = (Vec3f) s2.getPosition().sub(s1.getPosition());
// s2 velocity relativ to s1
Vec3f vel = (Vec3f) s2.getVelocity().sub(s1.getVelocity());
float dot = pos.dot(vel);
if(dot>0) // if s2 is moving away from s1 no collision
return false;
// calculates the nearest point from s1 to the moving line of s2
// p: nearest point on the line(s2.p + x * s2.v) to s1
// lenquad gives back the length of a Vector with out pulling the squarroot
float vellenquad = vel.lenquad();
float x = (-dot)/vellenquad;
Vec3f p = new Vec3f();
//the second argument of add and mul methods is where the result is saved
pos.add(vel.mul(x, p),p);
float distquad = p.lenquad(); // distance² from s1 to line: s2.p + x * s2.v
float mindist = s1.getRadius() + s2.getRadius();
float mindistquad = mindist * mindist;
if(distquad>mindistquad)
return false; // no collision cause the moving line of s2 is never near s1
double fen = Math.sqrt(mindist - distquad); //pytagoras
double vellen = Math.sqrt(vellenquad); // length of velocity vector
// x value of the collision, in the line function s2.p + x * s2.v
double fenx = x - fen/vellen;
if(fenx > 1)
return false; // on a way to collision but not this frame
// normal vector on which the velocity vector from both sphere gets refelcted after the collision
Vec3f normal = vel.mul((float)(-fen/vellen));
normal.add(p, normal);
normal.mul(s1.getRadius()/mindist, normal);
// exact position where both sphers collide
Vec3f colpos = normal.add(s1.getPosition());
//percenteg of movment both sphers went before the collision, indicates how much they still have to travel(permoved * s1.vel for excample)
double permoved = fenx / x; // percentage of the movment of both spheres until collision
fireEvent(new CollisionEvent(s1, s2, normal, colpos, permoved));
return true;
}