My collision detection + reflection works just fine (see here). First you need a boundary box as you will have this already implemented. Boundary boxes are generally vertices having each in 2D an X and Y coordinate which define the outer structure of an object.
To generally calculate the angle of a boundary, I use in C++ an atan function, which returns the angle of a vector within a coordinate system:
double GetAngleofVector(vector2 aVec)
{
double angle = atan2(aVec.Y,aVec.X)
return angle;
}
However, sticking strictly to vectors , this is unnecessary and much easier to do with raw vector calculations. Now, if you have a collision detection in place (e.g. SAT), to calculate the reflection angle, you need to think of thee cases and their 'physics'.
A) a circle reflected against a circle
B) a circle reflected against a boundary
C) a boundary reflected against a boundary
i) corner of Object 1 hits boundary of Object 2
ii) corner of Object 1 hits corner of boundary 2
iii) same as i, only reverse objects and hence calculations stay the same
There are good tutorials available for circle vs boundary (see e.g. here and here) and for rectangle vs rectangle with added rotation (see. e.g. here with Java Code sample).
For the simple case--bouncing of a wall, you need to get the projection of your velocity vector onto both the direction of the boundary and the direction perpendicular to the boundary. Call the boundary "colliding_boundary", simply a vector of the two vertices that span it. (Construct your own vector class "vector2" with the float member variables x and y).
vector2 colliding_boundary;
colliding_boundary.x = vertice_2.x-vertice_1.x
colliding_boundary.y = vertice_2.y-vertice_1.y
To obtain the normal from any vector given, I use the standard formula. In 2D space that's relatively easy:
vector2 GetNormal( vector2 const &A )
{
return vector2(-A.Y,A.X);
}
However, two more very useful formulas for 2D game engine development are the dot product and the unit vector along some original vector.
vector2 GetProjection(vector2 const &A, vector2 const &B)
{
vector2 dir=GetUnitVector(B);
double p_length = DotProduct(A,dir);
vector2 proj = p_length*dir;
return proj;
}
vector2 GetPerpendProjection(vector2 const &A, vector2 const &B)
{
vector2 dir=GetUnitVector(B);
double p_length = DotProduct(A,dir);
vector2 at = p_length*dir;
vector2 an = A-at;
return an;
}
Finally, I apply two compact functions to obtain the two aforementioned projections of your object's original velocity vector.
vector2 GetProjection(vector2 const &A, vector2 const &B)
{
vector2 dir=GetUnitVector(B);
double p_length = DotProduct(A,dir);
vector2 proj = p_length*dir;
return proj;
}
vector2 GetPerpendProjection(vector2 const &A, vector2 const &B)
{
vector2 dir=GetUnitVector(B);
double p_length = DotProduct(A,dir);
vector2 at = p_length*dir;
vector2 an = A-at;
return an;
}
Passing your velocity vector and boundary into those two functions gets you the two necessary vectors to get your object bouncing.
Remember, the resulting velocity is simply the reverse of the vector projection that is perpendicular to the wall (reflection!), while the velocity along the wall is kept.
So your final velocity would be:
vector2 v_final = GetProjection(speed_vector, colliding_boundary) - GetPerpendProjection(speed_vector, colliding_boundary).
For visualization I added a the demo link of my own game (mpeg) above. Notice the yellow, red, blue and white vectors being drawn at runtime collision and representing, in order, the object's original velocity, boundary perpendicular projection, boundary projection and final velocity. (Note, my object is also rotating, but ignore this for now.)