5
\$\begingroup\$

According to the N Tutorials, after a projection-based collision (i.e, adding a minimum translation vector to an object's position in order to bring it out of collision), bounce and friction are applied with the following three steps:

  • split velocity vector into two components: one parallel and one perpendicular to the collision surface

  • calculate bounce using the perpendicular component

  • calculate friction using the parallel component

I am assuming that, by "velocity vector", the tutorial refers to the object's current velocity.

How is this done? And, please try to keep it low-level so as not to confuse someone who knows essentially nothing about physics.

\$\endgroup\$
5
\$\begingroup\$

The "velocity vector" is the difference between the velocities of the two objects. When colliding with a static (unmoving) object (such as the level), the "velocity vector" is indeed its current velocity.

Normally, the collision surface's direction will be represented by a "normal" -- a vector of length 1 that points in the direction the surface is facing.

If you multiply the normal by the dot-product of the normal and the velocity vector (the dot product is a simple formula I'll explain below), you'll get the component of the velocity vector that's in the same axis as the normal (which is the perpendicular component -- the normal is perpendicular to all vectors along the surface).

If we subtract the perpendicular component from the velocity vector, we get the parallel component. That's to say, if we changed the velocity as little as possible to prevent it from going through the surface -- now it's going across the surface.

The dot product I mentioned before multiplies the corresponding elements of each vector together and adds them all together. So if you have velocity vector V and normal vector N, the dot product d is:

d = Vx * Nx + Vy * Ny + Vz * Nz

The "perpendicular component" P is the normal multiplied by that dot product:

P = (Nx * d, Ny * d, Nz * d)

This is going through the surface, though. So if we subtract it from the velocity vector V we get the parallel component (let's call it A for "across"):

A = V - P

And if we subtract P from that, we get the bounce vector B:

B = A - P

This is all true in both 2D and 3D. For the 2D version, just take out the parts with Z:

d = Vx * Nx + Vy * Ny

P = (Nx * d, Ny * d)


Let's bring it all together with how we'd modify the velocity when colliding with a static object.

First, you can stop moving through the object by subtracting P from V:

V = V - P

This is the same as calculating the "across" vector, A. Now, if you want to apply friction to the object, you can do it like so:

V = V - (A * f)

...where f is a "friction factor". 0 means no friction, 1 means the object stops immediately due to friction. When an object is ontop of another object, they're colliding over and over again due to gravity, so you'll usually want to have "friction" be really small to not cancel out all attempts to move across a surface over a few frames of simulation, and you might want to calculate the amount of friction by fancier means than just a fixed value, but I won't get into that here.

Finally, you can use a "bounce factor" b to apply bounce:

V = V - (P * b)

A bounce factor of 0 will mean no bouncing, 1 will mean full bounce.

\$\endgroup\$
  • \$\begingroup\$ This may be a little late, but I still have one question. You said the velocity vector is the difference between the velocities in the two objects, however, this could either be (object a's velocity - b's velocity) or (b's velocity - a's velocity). If I am trying to add bounce and friction to object a, which of these two should I use to calculate the velocity vector? \$\endgroup\$ – tobahhh Jun 30 '18 at 15:08
  • \$\begingroup\$ Also let's say I'm not colliding with a static object; rather, I have two moving objects. What should I do? \$\endgroup\$ – tobahhh Jul 1 '18 at 14:55
  • 1
    \$\begingroup\$ Av - Bv. The velocity vector when colliding with a static object is still just the difference between the velocities in the two objects, where the second object's velocity is 0. Av - Bv = Av - 0 = Av. \$\endgroup\$ – Jibb Smart Jul 2 '18 at 2:37
  • 1
    \$\begingroup\$ There are other complications with dynamic objects, though. When colliding with a static object (0 velocity and infinite mass), bounce factor of 0 and friction factor of 1 will bring you to a velocity of 0. But with dynamic collisions 0 is relative and depends on the masses and velocities of the objects involved. The relative0 vector is the weighted average of their velocities, weighted by their masses. This complicates the calculations of the friction vector and bounce vector \$\endgroup\$ – Jibb Smart Jul 2 '18 at 2:39
  • 1
    \$\begingroup\$ Probably the easiest way to do this is to calculate relative0 at the beginning, subtract it from the velocities of both objects, do all of the above calculations as if they were each colliding with a static object, then add relative0 to both velocities at the end. \$\endgroup\$ – Jibb Smart Jul 2 '18 at 2:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.