/** * collision_detection4.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 bounding boxes of the two objects. * The two objects have different masses (illustrated by using different diameters) * and different initial velocities. * * The two objects are different non-circular shapes. * * 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 d1w, d1h, d2w, d2h; // bounding box dimensions of each object boolean running; // flag indicating that the simulation is running /** * setup() */ void setup() { size( 800,600 ); // set the objects' dimensions in proportion to their respective masses d1w = d * m1; d1h = d1w * 1.5; d2w = d * m2; d2h = d2w * 0.75; 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, d1w, d1h ); fill( #006600 ); ellipse( p2.x, p2.y, d2w, d2h ); noFill(); stroke( #aaaaaa ); rect( p1.x, p1.y, d1w, d1h ); rect( p2.x, p2.y, d2w, d2h ); // 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() ) { println( "collide!" ); 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-d1w )) v1.x = - v1.x; if (( p1.y < 0 ) || ( p1.y > height-d1h )) v1.y = - v1.y; if (( p2.x < 0 ) || ( p2.x > width-d2w )) v2.x = - v2.x; if (( p2.y < 0 ) || ( p2.y > height-d2h )) 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. * we have to check if each corner of bounding box of each object is contained within the bounding box of the other. * note that we have to check both, since the objects are not the same size as each other. */ boolean isCollision() { if ((( p2.x <= p1.x + d1w ) && ( p1.x + d1w <= p2.x + d2w ) && ( p2.y <= p1.y + d1h ) && ( p1.y + d1h <= p2.y + d2h )) || // is lower right corner of p1 inside p2? (( p2.x <= p1.x ) && ( p1.x <= p2.x + d2w ) && ( p2.y <= p1.y + d1h ) && ( p1.y + d1h <= p2.y + d2h )) || // is lower left corner of p1 inside p2? (( p2.x <= p1.x + d1w ) && ( p1.x + d1w <= p2.x + d2w ) && ( p2.y <= p1.y ) && ( p1.y <= p2.y + d2h )) || // is upper right corner of p1 inside p2? (( p2.x <= p1.x ) && ( p1.x <= p2.x + d2w ) && ( p2.y <= p1.y ) && ( p1.y <= p2.y + d2h )) || // is upper left corner of p1 inside p2? (( p1.x <= p2.x + d2w ) && ( p2.x + d2w <= p1.x + d1w ) && ( p1.y <= p2.y + d2h ) && ( p2.y + d2h <= p1.y + d1h )) || // is upper left corner of p2 inside p1? (( p1.x <= p2.x ) && ( p2.x <= p1.x + d1w ) && ( p1.y <= p2.y + d2h ) && ( p2.y + d2h <= p1.y + d1h )) || // is upper right corner of p2 inside p1? (( p1.x <= p2.x + d2w ) && ( p2.x + d2w <= p1.x + d1w ) && ( p1.y <= p2.y ) && ( p2.y <= p1.y + d1h )) || // is lower left corner of p2 inside p1? (( p1.x <= p2.x ) && ( p2.x <= p1.x + d1w ) && ( p1.y <= p2.y ) && ( p2.y <= p1.y + d1h ))) { // is lower right corner of p2 inside p1? return( true ); } else { return( false ); } } // end of isCollision()