How to calculate bounce angle?

Moulde picture Moulde · Feb 21, 2009 · Viewed 77.6k times · Source

I played around with it for a while, but I simply can't figure it out.

I made a tank that fires missiles, and when the missiles hit the walls, I want them to bounce off, but I want them to bounce off to the right angle.

Right now I haven't got any obstacles, the missiles just bounce off when they get outside the viewportRectangle I made.

Is the solution I'm looking for quite advanced?

Is there a relativly simple way to do it?

Answer

Gareth Rees picture Gareth Rees · Feb 21, 2009

You might think that because your walls are aligned with the coordinate axes that it makes sense to write special case code (for a vertical wall, negate the x-coordinate of the velocity; for a horizontal wall, negate the y-coordinate of the velocity). However, once you've got the game working well with vertical and horizontal walls, probably the next thing you'll think is, "what about walls at arbitrary angles?" So it's worth thinking about the general case from the beginning.

In the general case, suppose your missile has velocity v and hits a wall with surface normal n.

Missile with vector v about to obliquely hit a wall with surface normal n.

Split v into components u perpendicular to the wall and w parallel to it.

Right-angled triangle with hypotenuse for v, short side u parallel to wall and long side w parallel to wall.

Where:

u = (v · n / n · n) n
w = vu

Here, v · n is the dot product of the vectors v and n. See the link for an explanation of how to compute it. The dot product n · n evaluates to the square of the length of the normal vector; if you always keep your normals in the form of unit vectors then n · n = 1 and you can omit the division.

After bouncing, the component of motion parallel to the wall is affected by friction f, and the component perpendicular to the wall is affected by elasticity, which can be given in the form of a coefficient of restitution r.

So the velocity after the collision is v′ = f wr u. In a perfectly elastic, frictionless collision, v′ = wu; that is, the motion is reflected about the normal at the point of collision, as in the diagram given in Bill's answer.

This approach works just the same in three dimensions too.

(Obviously this is a very simplified notion of bouncing; it takes no account of angular momentum or deformation. But for many kinds of video games this kind of simplification is perfectly adequate.)