# Calculating direction after circle-circle collision

This topic is 455 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I know how to calculate the scalar of the velocity vector after a collision with 2 circles (as per this link: https://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-basics-and-impulse-resolution--gamedev-6331)

These circles cannot rotate and do not have friction but can have different masses, however I cannot seem to find out any way to find the unit vector that I need to multiply the scalar of velocity by to get the new velocity of the particles after the collision.

I also know how to check if 2 circles are colliding.

Also, I am only dealing with this in a purely "maths-sense" (ie. the circles have a center and a radius), and would like to know how I can represent these circles on the screen in python 3.0.

The vector class:

class Vector():
def __init__(self,x,y):
self.x = x
self.y = y

return Vector(self.x+newVector.x, self.y+newVector.y)

def subtract(self,newVector):
return Vector(self.x-newVector.x, self.y-newVector.y)

def equals(self, newVector):
return Vector(newVector.x,newVector.y)

def scalarMult(self, scalar):
return Vector(self.x*scalar, self.y*scalar)

def dotProduct(self, newVector):
return (self.x*newVector.x)+(self.y*newVector.y

def distance(self):
return math.sqrt((self.x)**2 +(self.y)**2)

The circle class:

class Particles():
def __init__(self,currentPos, oldPos, accel, dt,mass, center, radius):
self.currentPos = currentPos
self.oldPos = oldPos
self.accel = accel
self.dt = dt
self.mass = mass
self.center = center

def doVerletPosition(currentPos, oldPos, accel, dt):
a = currentPos.subtract(oldPos)
c = accel.scalarMult(dt)
d = c.scalarMult(dt)

def doVerletVelocity(currentPos, oldPos, dt):

return True
else:
return False

I do know about AABBs, but I am only using around 10 particles for now, and AABBs are not necessary now.

##### Share on other sites

The usual billiard physics will hopefully help you. It can be narrow down to weighted disks easily. I haven't read that link thought. But at first glance it covers what you are looking for.

Edited by _Silence_

##### Share on other sites

Ah that is somehow easy Its not that hard:

- You take the difference between the two centers in world space: R = B - A

- Normalize that and you have your direction: N = R / |R|

- Calculate the penetration distance by subtracting the summed radius of both circles from the projected difference by the direction (btw: This distance is the length of the difference): d = (RadiusA+RadiusB) - Dot(R, N)

- Calculate relative velocity: VAB = VA - VB

- Calculate impulse strength: j = -(1 + e) * Dot(VAB, N) / (1/MassA + 1/MassB);

- Calculate and apply impulse on velocities:

VA -= j * (1 / MassA) * N

VB += j * (1 / MassB) * N

Thats one step. Next step is to resolve penetration. This is handled in the "how to create a custom 2D physics engine" series as well - so check that out.

Edited by Finalspace

##### Share on other sites
Quote

Calculate impulse, done: I = N * d

This obviously has not the dimensions of an impulse.

##### Share on other sites
34 minutes ago, Dirk Gregorius said:

This obviously has not the dimensions of an impulse.

Right, its not an impulse at all! My bad. Its a minimum translation vector!

An impulse would be at the relative velocity projected along the direction divided by the sum of their masses.

Edited by Finalspace

##### Share on other sites
Quote

An impulse would be at the relative velocity projected along the direction divided by the sum of their masses.

Nope, impulse = mass * velocity. Not velocity divided by mass. You are also not taking the rotational effects into account. E.g. the inertia contribution seen by the impulse at the application point in the direction of the normal. This is sometimes referred to as effective mass.

float EffectiveMassInv = 1/m1 + 1/m2 + dot(n, InvI1 * n) + dot(n, InvI2 * n);
float EffectiveMass = 1 / EffectiveMassInv;

Then you can compute equal and opposite impulses on each body like

float Lambda = EffectiveMass * -RelVelocity;
Body1->ApplyImpulseAt( -n * Lambda, ContactPoint );
Body2->ApplyImpulseAt( n, Lambda, ContactPoint );

Edited by Dirk Gregorius

##### Share on other sites
On 17.10.2017 at 7:56 PM, Dirk Gregorius said:

Nope, impulse = mass * velocity. Not velocity divided by mass. You are also not taking the rotational effects into account. E.g. the inertia contribution seen by the impulse at the application point in the direction of the normal. This is sometimes referred to as effective mass.


float EffectiveMassInv = 1/m1 + 1/m2 + dot(n, InvI1 * n) + dot(n, InvI2 * n);
float EffectiveMass = 1 / EffectiveMassInv;

Then you can compute equal and opposite impulses on each body like


float Lambda = EffectiveMass * -RelVelocity;
Body1->ApplyImpulseAt( -n * Lambda, ContactPoint );
Body2->ApplyImpulseAt( n, Lambda, ContactPoint );

The OP dont care about rotations, so i havent included it.

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 9
• 13
• 9
• 9
• 15
• ### Forum Statistics

• Total Topics
634074
• Total Posts
3015345
×