I'm trying to get a moving circular object to bounce (elastically) off of an immovable circular object. Am I doing this right? (The results look right, but I hate to trust that alone, and I can't find a tutorial that tackles this problem and includes the nitty gritty math/code to verify what I'm doing). If it is right, is there a faster or more elegant way to do this?

Note that this is the moving circle, and EntPointer is the immovable circle.

        //take vector separating the two centers <x, y>, and then get unit vector of the result:
        MathVector2d unitnormal = MathVector2d(this -> Retxpos() - EntPointer -> Retxpos(), this -> Retypos() - EntPointer -> Retypos()).UnitVector();

         //take tangent <-y, x> of the unitnormal:
        MathVector2d unittangent = MathVector2d(-unitnormal.ycomp, unitnormal.xcomp);

        //the velocity of the moving object in vector form:
        MathVector2d V1 = MathVector2d(this -> Retxvel(), this -> Retyvel());

        //Calculate the normal and tangent vector lengths of the velocity: (the normal changes, the tangent stays the same)
        double LengthNormal = DotProduct(unitnormal, V1);
        double LengthTangent = DotProduct(unittangent, V1);

        MathVector2d VelVecNewNormal = unitnormal.ScalarMultiplication(-LengthNormal); //the negative of what it was before

        MathVector2d VelVecNewTangent = unittangent.ScalarMultiplication(LengthTangent); //this stays the same

        MathVector2d NewVel = VectorAddition(VelVecNewNormal, VelVecNewTangent); //combine them

        xvel = NewVel.xcomp; //and then apply them
        yvel = NewVel.ycomp;

Note also that this question is just about velocity, the position code is handled elsewhere (in other words, assume that this code is implemented at the exact moment that the circles begin to overlap).

Thanks in advance for your help and time!


I think the more elegant, and guaranteed correct way to do this is just use the vector reflection equation to reflect the velocity of the circle around the normal of the collision:

MathVector2d NewVel = VectorSubtraction(V1, unitNormal.ScalarMultiplication(2.0 * DotProduct(V1, unitNormal))

This amounts to 1 dot product, 3 scalar multiplications, and 1 vector subtraction. Before you had 2 dot products, 4 scalar multiplications, and 1 vector addition, and I'm not entirely sure the math is correct in all cases (consider the moving circle with velocity [1, -1] bouncing with a normal of [0, 1]).

From there, you can add some fanciness such as a coefficient of restitution, which is a figure representing how much of the circle's velocity is lost during the collision.

Also, some of this math changes if the objects have rotational velocity.

  • \$\begingroup\$ This is exactly what I was looking for; it works really well, thanks! \$\endgroup\$
    – MindSeeker
    Jun 6 '14 at 22:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .