I am working a 2d physics engine.

Polygon to polygon collision and velocity resolution works without issue, but I am struggling to get working circle to circle and circle to polygon velocity working as expected.

Here is a video the current version: https://www.youtube.com/watch?v=jVHN9Or9b1g.
As shown in the video, the angular velocity of the circles does not change upon collision.

Here is what should happen upon collision:

enter image description here

For example, if a car were to spin it's wheels on top of a sheet of wood, the wood would go flying in the direction that it's the tire is spinning.

enter image description here

Assistance would be much appreciated.

  • \$\begingroup\$ How are you handling the forces generated by friction? Are you tracking/solving for conservation of angular momentum? \$\endgroup\$
    – Basic
    Mar 30 at 1:37
  • \$\begingroup\$ @basic Each circle and node has a friction coefficient. Circle to circle angular velocity works properly if the a circle is already spinning, but that's not the problem that I'm trying to solve here. The problem is that when a circle has no angular velocity and it collides with a another object, depending on how the circle hit that object it's angular velocity should change (i.e. if a node hit it at the right angle it should begin to spin) \$\endgroup\$
    – TrippR
    Mar 30 at 2:18
  • \$\begingroup\$ How is your code imparting motion at the point of collision currently? Can you show the relevant code or pseudocode? \$\endgroup\$
    – DMGregory
    Mar 30 at 11:32

1 Answer 1


One answer is too short to cover all the concepts. So to maybe help you gather your thoughts...

This answer will represent the use of 2D vector cross and dot products to extract the two vectors that represent imparted linear and angular forces from a calculated collision vector at the point of collision.

There are subtle differences between 3D and 2D solutions, I will assume you are wanting a 2D solution. Most of this answer applies to both 2D and 3D, but a 3D problem needs to be simplified to a 2D solution before it can be solved and is not included.


You show 3 illustrations and your language implies you see them as three different solutions. However you can see them as 3 examples of the same problem. A problem we can ultimately simplify to three points, two vectors, and two scalars.

Lets' assume that the

  • collision is at a single infinitesimally small instance of time,

  • that there is a single infinitesimally small point of contact between the two objects,

  • that both objects have a velocity vector v and angular velocity w.

    I will use v and w as subscripts for algebraic representations.

  • that the points A and B (See Fig1) are at the center of mass of the two objects

  • That the mass of both objects are equal (or are substituted with the unit value 1)

  • that the problem is 2D

Note You say in the comments "...circle has no angular velocity..." There is no reason to make a special case for zero angular velocity.

To help visualize the problem see the following illustration fig1.

A collision between two objects

A collision between two objectsfig1

  • Av Bv linear velocities
  • Aw Bw angular velocities
  • Avw derived surface velocity (missing Bvw)

All motion is relative, the above image is from an outside perspective, however we will reduce the problem to objects' A point of view.

Vector math

The most important details you make no mention of in your question, the point C (point of contact) and the Normal (along the line from As' center of mass and the point of contact) and Tangent (At 90deg to the normal) vectors

I will assume you are familiar with vectors but not practiced. The Normal and Tangent are vectors onto which we will project the various relevant vectors derived from the problem (namely Av, Bv, Awv derived from Aw and Bwv (not illustrated) derived from Bw.

In fig2 we remove the objects and show the tangent and normal vectors. We have an arbitrary vector V that will be projected onto the normal and tangent vectors.

The orientation of the vectors are irrelevant as shown in the inset fig2 (rotates all vectors to align the tangent with the x Axis)

Projecting vectorsfig2

Dot and Cross

These two algebraically operation should become second nature to game programmers, they represent much more than is illustrated in this answer.


We use the dot product of two vectors to project the second vector onto the first (See fig2 V projected as Vi)

Dot product is written algebraically as A⋅B where A is the tangent and B is the vector V

As pseudo code (unknowns as ?)

A = {x: ?, y: ?}   // 2D Vector
B = {x: ?, y: ?}   // 2D Vector
dot = A.x * B.x + A.y * B.y  // Scalar value 


We use the cross product of two vectors to project the second vector onto the vector at 90 deg from the first (See fig2 V projected as Vj)

Cross product is written algebraically as A⨯B where A is the tangent and B is the vector V the result is the projection of V onto the normal

As pseudo code (unknowns as ?)

A = {x: ?, y: ?}   // 2D Vector
B = {x: ?, y: ?}   // 2D Vector
cross = A.x * B.y - A.y * B.x  // Scalar value 

Scalar results

The dot and cross product return a single value (not vectors) and represent the relative length of the project vector along the resulting axis. Kind of but more (Area of Parallelogram created by the two vectors, sin and cos of angle between the two vectors (if both are normalized), and more abstract values)

Applying forces

From fig1

  • the Tangent vector represents the direction of the forces that apply rotational acceleration.

  • the Normal vector represents the direction of the forces that apply linear acceleration.

We will create a single vector representing all the velocities (thus forces) involved.

Which we will call Cv the result of adding Av + Bv + (Awv at point C) + (Bwv at point C)

Note that Awv and Bwv will be the along the tangent vector at C.

Now we have one vector Cv

Note to simplify the explanation I will normalize the Tangent and Normal vectors. From here on they represent unit vectors along the tangent (Tv) and normal (Nv). In practice there is no need to normalize, operations that would increase code source complexity and CPU load.

Change in linear velocity as a vector

To calculate the amount of force as a vector that will change the linear velocity of A we will scale the vector (Nv) by the cross product of CvTv to get a result vector as C1v

Change in angular velocity as a scalar

To calculate the amount of force as a vector that will change the angular velocity of A we will scale the vector (Tv) by the dot product of CvTv to get a result vector as C1wv

We add C1v to Av

We convert C1wv to angular velocity C1w and add it to Aw (you must account for distance C is from center of mass)

(Sorry for collisions I use an unconventional alignment (i hat along tangent))


No not by a long shot. However the basics are there. The use of dot and cross product to extract the linear and rotational force vectors from a single collisional vector is the fundamental part of the solution.

Getting the collision vector will depend on mass, friction/s, etc... applying the resulting linear and angular values will also depend on inertia, restitution, and more


For more and detail information some wiki links.


You must log in to answer this question.

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