So I have an object moving in a direction towards a fixed horizontal or vertical wall. How do I compute the angle that the object should bounce off at? The object can approach the wall at an arbitrary angle.
3 Answers
If you know the wall's normal vector and have an incoming direction for the object, then what you want is the reflection of a vector across a plane.
If n is a normalized vector, and v is the incoming direction, then what you want is −(2(n · v) n − v). The minus sign accounts for the fact that the reflection formula doesn't actually reverse the direction, as an object's velocity would reverse.
This answer is given in terms of vector math, not an angle, because that's usually preferable if you don't have an explicit reason to use an angle. Note that if you must talk about angles, the angle of reflection is equal to the angle of incidence. If the angle is measured from the normal, the outgoing angle is the negation of the incoming angle; if the angle is measured from the wall, then it's the complement of the incoming angle.
-
\$\begingroup\$ Great explanation. It worked out great for me! Thanks! \$\endgroup\$– DRiFTyFeb 10, 2012 at 20:54
You didn't specify if it was a 2D or 3D game. But if it's a 2D game and your walls are guaranteed to be horizontal or vertical and you just want to bounce the object off them, there's a much easier way than having to deal with reflections.
Simply negate the X-component of the object's velocity when hitting a vertical wall, or the Y-component of the object's velocity when hitting an horizontal wall. Example:
if( /* hit vertical wall */ )
{
object.velocity.x *= -1;
}
if( /* hit horizontal wall */ )
{
object.velocity.y *= -1;
}
But if you really care about knowing the angle, then in general terms, the angle of reflection is the same as the angle of incidence. This angle is measured in relation to the wall's normal. Here's a picture that should make it clear:
In case you ever need to handle this for arbitrary walls, you'll need to look into how to reflect a vector. It's really just a small formula that takes the wall's normal and the incidence vector, and returns the reflected vector for you. Here's the formula XNA uses:
public static Vector3 Reflect(Vector3 vector, Vector3 normal)
{
return vector - 2 * Vector3.Dot(vector, normal) * normal;
}
And for 2D you could just do:
public static Vector2 Reflect(Vector2 vector, Vector2 normal)
{
return vector - 2 * Vector2.Dot(vector, normal) * normal;
}
-
\$\begingroup\$ Sorry about that, it is a 2D game. I would like to keep it based on angle because like you said I would like to be able to use any wall. Thanks! \$\endgroup\$– DRiFTyFeb 10, 2012 at 20:53
-
\$\begingroup\$ I edited it to cover 2D too. Actually, it's the same, just with 2D vectors, same operations and formulas \$\endgroup\$ Feb 11, 2012 at 2:10
-
\$\begingroup\$ A wall in a 2D game might be angled, so the statement
if it's a 2D game and your walls are guaranteed to be horizontal or vertical
is not correct. The second part of the answer adresses the correct implementation. IMHO, the order of the parts should be reversed, presenting the general solution first and in enphasis, while the right-angle solution is presented as a simplification for the exceptional case. \$\endgroup\$ Jan 15, 2019 at 21:12
This is just about reflecting a vector along the walls normal vector.