/** * collision_detection3.pde * * This program demonstrates collision detection in two dimensions. * Two objects move toward each other and stop when they collide. * Collision is detected by comparing the distance between the objects' centers. * This only works for circular objects! * The two objects have different masses (illustrated by using different diameters) * and different initial velocities. * * created: 4-oct-2011/sklar * */ int d = 100; // diameter multiplier for both objects PVector v1, v2; // velocities of each object PVector p1, p2; // positions of each object float m1 = 2, m2 = 1; // mass of each object float d1, d2; // diameters of each object boolean running; // flag indicating that the simulation is running /** * setup() */ void setup() { size( 800,600 ); // set the objects' diameters in proportion to their respective masses d1 = d * m1; d2 = d * m2; v1 = new PVector( 2, 3, 0 ); p1 = new PVector( 10, 10, 0 ); v2 = new PVector( -1, -1, 0 ); p2 = new PVector( 690, 10, 0 ); ellipseMode( CORNER ); running = true; } // end of setup() /** * draw() */ void draw() { if ( running ) { // clear screen background( #ffffff ); // draw two objects stroke( #333333 ); fill( #000066 ); ellipse( p1.x, p1.y, d1, d1 ); fill( #006600 ); ellipse( p2.x, p2.y, d2, d2 ); noFill(); stroke( #aaaaaa ); // update positions of each object p1.x += v1.x; p1.y += v1.y; p2.x += v2.x; p2.y += v2.y; // did we collide? if ( isCollision() ) { float dv1x = ( m1 - m2 )/( m1 + m2 ) * v1.x + ( 2 * m2 )/( m1 + m2 ) * v2.x; float dv1y = ( m1 - m2 )/( m1 + m2 ) * v1.y + ( 2 * m2 )/( m1 + m2 ) * v2.y; float dv2x = ( 2 * m1 )/( m1 + m2 ) * v1.x + ( m2 - m1 )/( m1 + m2 ) * v2.x; float dv2y = ( 2 * m1 )/( m1 + m2 ) * v1.y + ( m2 - m1 )/( m1 + m2 ) * v2.y; v1.x = dv1x; v1.y = dv1y; v2.x = dv2x; v2.y = dv2y; } // bounce off of the edge of the display window if (( p1.x < 0 ) || ( p1.x > width-d1 )) v1.x = - v1.x; if (( p1.y < 0 ) || ( p1.y > height-d1 )) v1.y = - v1.y; if (( p2.x < 0 ) || ( p2.x > width-d2 )) v2.x = - v2.x; if (( p2.y < 0 ) || ( p2.y > height-d2 )) v2.y = - v2.y; } } // end of draw() /** * keyPressed() */ void keyPressed() { if (( key == 'q' ) || ( key == 'Q' )) { exit(); } else if (( key == 'r' ) || ( key == 'R' )) { restart(); } else if (( key == 's' ) || ( key == 'S' )) { running = ! ( running ); } } // end of keyPressed() /** * restart() */ void restart() { v1.set( 2, 3, 0 ); p1.set( 10, 10, 0 ); v2.set( -1, -1, 0 ); p2.set( 690, 10, 0 ); } // end of restart() /** * isCollision() * this function returns true if the two objects have collided; false otherwise */ boolean isCollision() { float r1 = d1/2; // radius of first object PVector p1center = new PVector( p1.x + r1, p1.y + r1 ); // center of first object float r2 = d2/2; // radius of second object PVector p2center = new PVector( p2.x + r2, p2.y + r2 ); // center of second object float d = sqrt( sq(p1center.x - p2center.x) + sq(p1center.y - p2center.y )); // distance between the centers of the two objects if ( d < r1 + r2 ) { return( true ); } else { return( false ); } } // end of isCollision()