// Changes the direction of the ball -- This is a hard thing to explain with out // a diagram, thus I HIGHLY suggest looking at Diagram.bmp -- I'll be referring to the // "names" of vectors that I used in the bitmap void ChangeDirection(int wallIndex) { float vecX, vecY; // Used to store the vector components made by two wall points float dotProduct; // Used to hold the dot product between two vectors VECTOR normal; // This corresponds to 'n' in Diagram.bmp // It will be used to store the normal to the "wall" (ie a vector that // is 90° to the wall represented by (vecX, vecY)) VECTOR vPrime(ball.getDirX(), ball.getDirY()); // This corresponds to v' in Diagram.bmp // It is the direction the ball is // traveling flipped (we'll flip it // in the next line of code) vPrime.flip(); // There it's flipped :) VECTOR a; // This corresponds to vector 'a' on the diagram -- What it will hold // is the FLIPPED traveling vector of the ball PROJECTED onto the // normal of the wall we've collided with (see Diagram.bmp for clearer picture :) VECTOR newDir; // This will hold the NEW DIRECTION the ball should travel in // This will correspond to 'd' in Diagram.bmp // Determine which wall we collided with switch(wallIndex) { case TOP: // We've collided with the top of the window // Get the vector (x,y) for the top edge vecX = float(wall[TOP].pt2.x - wall[TOP].pt1.x); vecY = float(wall[TOP].pt2.y - wall[TOP].pt1.y); break; case BOTTOM: // We've collided with the bottom of the window // Get the vector (x,y) for the bottom edge vecX = float(wall[BOTTOM].pt2.x - wall[BOTTOM].pt1.x); vecY = float(wall[BOTTOM].pt2.y - wall[BOTTOM].pt1.y); break; case LEFT: // We've collided with the left of the window // Get the vector (x,y) for the left edge vecX = float(wall[LEFT].pt2.x - wall[LEFT].pt1.x); vecY = float(wall[LEFT].pt2.y - wall[LEFT].pt1.y); break; case RIGHT: // We've collided with the right of the window // Get the vector (x,y) for the right edge vecX = float(wall[RIGHT].pt2.x - wall[RIGHT].pt1.x); vecY = float(wall[RIGHT].pt2.y - wall[RIGHT].pt1.y); break; } // Calculate the normal to this vector (ie the vector that is perpendicular // to the "wall" from (vecX, vecY)) // This corresponds to 'n' in Diagram.bmp normal.setX(-1 * vecY); normal.setY(vecX); normal.normalize(); // Make "normal" be a unit vector dotProduct = vPrime * normal; // Calculate the dot product between // the ball's flipped direction vector // and a normal to the wall we've collided with // Calculate the vector 'a' -- This is simply using the linear algebra (vector math) // definition of "projection of a vector unto another" -- This corresponds to 'a' in // Diagram.bmp a.setX(dotProduct * normal.getX()); a.setY(dotProduct * normal.getY()); /* Now this is not tricky, but it calls for a little thinking and visualizing. If you look at Diagram.bmp you see 'a' is the vector projected onto 'n' Well visualize that you take 'a' double it's length (hence the multiply by 2) Now if 'a' is doubled and you moved v' so that the head of v' was touching the head of "doubled a", you would see that 'd' (the direction we want to head) would make a triangle with these two vectors (ie it's the result of subtracting the two vectors -- Recall "How to subtract two vectors" :). Thus, simply subtract 2 * a from v' and presto, you have you new direction to travel in. */ newDir.setX(2 * a.getX() - vPrime.getX()); newDir.setY(2 * a.getY() - vPrime.getY()); ball.setDirection(newDir); // Set our new direction }