Saturday, December 11, 2010

Post-collision movement, part deux

So I'm going to talk about some vector math. The reason is that much is needed in order to do proper object movement when a collision occurs. Let's start with a hypothetical situation.

Say an object is falling straight down due to gravity; its velocity is strictly in the -y direction. If it's oriented so that, when it lands, it lays flat against the ground, then the point of impact can be approximated as being directly below the object's center of gravity. In that case, the object will bounce straight back up in the air, with no imparted rotation.

However, if the object falls such that the point of impact is elsewhere (say, on a vertex of the shape), then the movement is more complicated. These two scenarios are depicted in the diagram below (in opposite order unfortunately).


On the right is a point of impact directly below the center of gravity, and the left demonstrates impact at a vertex.

When an object collides with another at a point other than one directly in line with its velocity vector, we have to take into account just how far away that point is from the center of mass with respect to the velocity vector. We can find this by finding the magnitude of the rejection vertex of some vertex vector r onto the object's velocity vector v. How do we do this?

A projection of one vector a onto a second b can be thought of as finding a vector c that points in the same direction as b but of a magnitude represented by a being "projected" onto b. Make sense?  Ok maybe not.

Picture a right triangle aligned on the x-axis with the right angle on the bottom right. The leg on the bottom (along the x-axis) is the projection of the hypotenuse onto the x-axis. Make any more sense? Ok, how about a picture?



Get it now? Wonderful! So, why was I talking about the projection of a vector, you ask? Well, in order to get the aforementioned rejection vector of a vertex vector r, we need the projection vector of r. We can see graphically how to find each of them and it's not difficult. But we don't code in graphs and pictures; we code in math. So how do we find them mathematically?

Turns out that the projection of r onto v is equal to (· v') v', where v' here represents the unit vector of v (simply because I don't know how to get carets on top of arbitrary letters). The rejection, therefore, is just the original vector r minus its projection onto v. See the image below for a better display.


So we have the rejection of r onto v. Hooray! But why does this matter? It matters because the ratio of the magnitude of the rejection vector to the magnitude of the vertex vector tells us how much energy to impart to translational motion of the object post-collision, and how much to impart to rotational motion post-collision.

In a previous post I discussed how to find the angular velocity of an object post-collision. Now I'll talk briefly about how to get the translational motion. This is actually pretty straightfoward relative to the angular motion. I'm basically finding a new velocity vector that is symmetrical about the normal vector of the polygon against which it's colliding.

If an object is hitting the (flat) ground at an angle of incidence θ, then when it bounces off the ground, its angle of reflection will also be θ (think of light reflecting off a mirror). In this special case, the normal vector to the ground points straight up, so the new velocity vector is easy -- just invert the y-component (up instead of down). But what if the ground is not flat? What if it's at an angle? What is the normal vector then? Well, it turns out that we can find that using the vertices of the ground polygon. The normal vector u is the cross product of two vectors lying along two edges of the polygon, and those vectors are found by subtracting the vertices, as seen in the diagram below.

So u is our normal vector, and we want to normalize it to get û (normalization means adjusting the magnitude so that it equals 1). What do we do with û then? We need to find the projection of v onto u. Our new velocity v2 will be v1 + 2 (v1 · û)û. Here is a diagram to help visualize what this means:



We can see v1 coming in and striking the ground, which has a unit normal vector û. The reflected new velocity v2 can be seen as being the composite of v1 plus twice the projection of  v1 onto û. Voilà! The magnitude of the velocity will need to be adjusted, however, based on the point of impact as described previously in this post. As a result, we will have an accurately-behaving object in a simulated 3d environment.

Reading these posts, you may ask why it is that I go into such detail on these things. The reason is that it helps me in deducing solutions to problems. For instance, when I started this post, I didn't know the answer to how to find the new velocity. But through sketching and MSPainting, I was able to talk myself through the solution as I walk you through it. So if you find yourself bored reading these, I'm sorry, but it's necessary.

Your boredom fuels my productivity.

No comments:

Post a Comment