// Performs a simple collision between two Balls. It will update their velocities. // Returns a positive float 0-2, denoting the strength of the collision if there is one. // Returns negative if there is no collision. float collide(Ball A, Ball B) { float disX = A.pos.x - B.pos.x; float disY = A.pos.y - B.pos.y; float disR = A.rad + B.rad; if(disR*disR > (disX*disX + disY*disY)) // Stupid-simple Broad-phase. { PVector U1x, U1y, U2x, U2y; //Temp component Vect2Ds PVector axis = new PVector(disX, disY); //Axis Vect2D that we project on axis.normalize(); // Refine overlap float over = (disR - sqrt(disX*disX + disY*disY))*.5; // Push the Balls out of each other. A.pos.add(PVector.mult( axis, over )); // A out of B B.pos.add(PVector.mult( axis, -over )); // B out of A // Save out how direct the collisions were. // Useful for later calculations float aDot = axis.dot(A.vel); float bDot = -(axis.dot(B.vel)); // Project on axis to get New Velocities U1x = PVector.mult( axis, aDot); // Velocity Imparted on B from A U1y = PVector.sub( A.vel, U1x ); // Maintained Velocity for A U2x = PVector.mult( axis, -bDot); // Velocity Imparted on A from B ( Negative to reverse direction of Axis ) U2y = PVector.sub( B.vel, U2x ); // Maintained Velocity for B // Final Velocities. A.vel.set(PVector.add( U2x, U1y ) ); B.vel.set(PVector.add( U1x, U2y ) ); // Assume that the more direct a collision was ( as indicated by high scalar products ) // the "stronger" it was. This is useful for adding interest to the visualization. // Magnitude is not important for this purpose. return ( abs(aDot)+abs(bDot) ); } else { //No collision return -1; } }