# 2D Collision, Objet mass

## Recommended Posts

I'm making a 2D games engin, which includes a small physics engin

here is the code that controls the ellastic collision between 2 objects (\$hSprite1, \$hSprite2) inspired from This link

```Local \$dist = _GEng_SpriteToSprite_Dist(\$hSprite1, \$hSprite2) ; the distance between the 2 objects
Local \$nx, \$ny, \$gx, \$gy
\$nx = (\$hSprite2[\$_gSpr_PosX] - \$hSprite1[\$_gSpr_PosX]) / \$dist
\$ny = (\$hSprite2[\$_gSpr_PosY] - \$hSprite1[\$_gSpr_PosY]) / \$dist
\$gx = -1 * \$ny
\$gy = \$nx
; ---
Local \$v1n, \$v1g, \$v2n, \$v2g
\$v1n = \$nx * \$hSprite1[\$_gSpr_SpeedX] + \$ny * \$hSprite1[\$_gSpr_SpeedY]
\$v1g = \$gx * \$hSprite1[\$_gSpr_SpeedX] + \$gy * \$hSprite1[\$_gSpr_SpeedY]
\$v2n = \$nx * \$hSprite2[\$_gSpr_SpeedX] + \$ny * \$hSprite2[\$_gSpr_SpeedY]
\$v2g = \$gx * \$hSprite2[\$_gSpr_SpeedX] + \$gy * \$hSprite2[\$_gSpr_SpeedY]
; ---
If \$hSprite1[\$_gSpr_Masse] > 0 Then
\$hSprite1[\$_gSpr_SpeedX] = \$nx * \$v2n + \$gx * \$v1g
\$hSprite1[\$_gSpr_SpeedY] = \$ny * \$v2n + \$gy * \$v1g
EndIf
If \$hSprite2[\$_gSpr_Masse] > 0 Then
\$hSprite2[\$_gSpr_SpeedX] = \$nx * \$v1n + \$gx * \$v2g
\$hSprite2[\$_gSpr_SpeedY] = \$ny * \$v1n + \$gy * \$v2g
EndIf```

this code conciders that the 2 objects have the same mass, but i want to be able to compute collisions between object of different mass, and i don't know where to insert the mass variable (\$hSpriteX[\$_gSpr_Masse]) in the equations

##### Share on other sites

Look at the code in where you can enable mass on the balls.

Btw, there are plenty tutorial for collision detection in the web - just ask Google...

Br,

UEZ

Edited by UEZ

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

##### Share on other sites

I advise you get physics textbook

Momentum = mass * velocity

Total momentum before is the same as after.

##### Share on other sites

I'm making a 2D games engin, which includes a small physics engin

here is the code that controls the ellastic collision between 2 objects (\$hSprite1, \$hSprite2) inspired from This link

```Local \$dist = _GEng_SpriteToSprite_Dist(\$hSprite1, \$hSprite2) ; the distance between the 2 objects
Local \$nx, \$ny, \$gx, \$gy
\$nx = (\$hSprite2[\$_gSpr_PosX] - \$hSprite1[\$_gSpr_PosX]) / \$dist
\$ny = (\$hSprite2[\$_gSpr_PosY] - \$hSprite1[\$_gSpr_PosY]) / \$dist
\$gx = -1 * \$ny
\$gy = \$nx
; ---
Local \$v1n, \$v1g, \$v2n, \$v2g
\$v1n = \$nx * \$hSprite1[\$_gSpr_SpeedX] + \$ny * \$hSprite1[\$_gSpr_SpeedY]
\$v1g = \$gx * \$hSprite1[\$_gSpr_SpeedX] + \$gy * \$hSprite1[\$_gSpr_SpeedY]
\$v2n = \$nx * \$hSprite2[\$_gSpr_SpeedX] + \$ny * \$hSprite2[\$_gSpr_SpeedY]
\$v2g = \$gx * \$hSprite2[\$_gSpr_SpeedX] + \$gy * \$hSprite2[\$_gSpr_SpeedY]
; ---
If \$hSprite1[\$_gSpr_Masse] > 0 Then
\$hSprite1[\$_gSpr_SpeedX] = \$nx * \$v2n + \$gx * \$v1g
\$hSprite1[\$_gSpr_SpeedY] = \$ny * \$v2n + \$gy * \$v1g
EndIf
If \$hSprite2[\$_gSpr_Masse] > 0 Then
\$hSprite2[\$_gSpr_SpeedX] = \$nx * \$v1n + \$gx * \$v2g
\$hSprite2[\$_gSpr_SpeedY] = \$ny * \$v1n + \$gy * \$v2g
EndIf```

this code conciders that the 2 objects have the same mass, but i want to be able to compute collisions between object of different mass, and i don't know where to insert the mass variable (\$hSpriteX[\$_gSpr_Masse]) in the equations

I assume you mean how do you allow for the different masses in your calculations of the resulting speeds. Based on that here are my meandering thoughts, and there might be others who can give better answers as always.

The first thing I would think about is that enery and momentum must be conserved. So I would work out the momentum in x and y before the collision and make sure that the momentum was the same after the collision.

I would assume a perfectly elestic collision; ie no energy given upo to friction in the collision.

I don't actually know how 2 bodies respond to collisions so let's try a straight line collision.

Say the small one is S and the big one is G, velocity of S is Vs and for B it's Vb. Mass of S is Ws and of B is Wb. so

Initial total momentum is

Mt = Ms + Mb

= Wb * Vb + Ws * Vs

After the collision each some momentum will be transferred from one to the other, and what's lost by one is gained by the other.

The velocities after collision are say Rs and Rb for (rebound vel)

so

Ms * Rs + Mb * Rb = Ms * Vs + Mb * Vb (i)

Say the change in velocity for S is J. Then the change in velocity for B will be K given by

K*Mb = -J * Ms (ii)

Since

Rs = Vs + J

and

Rb = Vb - J * Ms/Mb

we can write (i) again lik ethis

Ms * (Vs + J) + Mb *(Vb - J * Ms/Mb) = Ms * Vs + Mb * Vb

which only has J as an unknown so we can work it out.

Now treat the X and Y components as I did the in-line example and I think you should be able to calculate the changes in velocity depending on the initial velocities and the relative masses.

Since this is written as I think it up it neds to be treated with sceptism, but so far it sounds reasonable to me.

EDIT: Typos

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

##### Share on other sites

Ok! thanks!

I inspired from the UEZ example and here is the result

```If Not __GEng_Sprite_IsSprite(\$hSprite2) Then Return SetError(1, 0, 0)
; ---
Local \$dist = _GEng_SpriteToSprite_Dist(\$hSprite1, \$hSprite2)
Local \$mass_tot = \$hSprite1[\$_gSpr_Masse] + \$hSprite2[\$_gSpr_Masse]
Local \$nx, \$ny, \$gx, \$gy
\$nx = (\$hSprite2[\$_gSpr_PosX] - \$hSprite1[\$_gSpr_PosX]) / \$dist
\$ny = (\$hSprite2[\$_gSpr_PosY] - \$hSprite1[\$_gSpr_PosY]) / \$dist
\$gx = -1 * \$ny
\$gy = \$nx
; ---
Local \$v1n, \$v1g, \$v2n, \$v2g
\$v1n = \$nx * \$hSprite1[\$_gSpr_SpeedX] + \$ny * \$hSprite1[\$_gSpr_SpeedY]
\$v1g = \$gx * \$hSprite1[\$_gSpr_SpeedX] + \$gy * \$hSprite1[\$_gSpr_SpeedY]
\$v2n = \$nx * \$hSprite2[\$_gSpr_SpeedX] + \$ny * \$hSprite2[\$_gSpr_SpeedY]
\$v2g = \$gx * \$hSprite2[\$_gSpr_SpeedX] + \$gy * \$hSprite2[\$_gSpr_SpeedY]
; ---
;calculate new vectors according to mass
\$v_p1 = (\$hSprite1[\$_gSpr_Masse] - \$hSprite2[\$_gSpr_Masse]) / \$mass_tot * \$v1n + 2 * \$hSprite2[\$_gSpr_Masse] / \$mass_tot * \$v2n
\$v_p2 = (\$hSprite2[\$_gSpr_Masse] - \$hSprite1[\$_gSpr_Masse]) / \$mass_tot * \$v2n + 2 * \$hSprite1[\$_gSpr_Masse] / \$mass_tot * \$v1n
; ---
If \$hSprite1[\$_gSpr_Masse] > 0 Then
\$hSprite1[\$_gSpr_SpeedX] = \$nx * \$v_p1 + \$gx * \$v1g
\$hSprite1[\$_gSpr_SpeedY] = \$ny * \$v_p1 + \$gy * \$v1g
EndIf
If \$hSprite2[\$_gSpr_Masse] > 0 Then
\$hSprite2[\$_gSpr_SpeedX] = \$nx * \$v_p2 + \$gx * \$v2g
\$hSprite2[\$_gSpr_SpeedY] = \$ny * \$v_p2 + \$gy * \$v2g
EndIf```

It works just as i need.

The very big problem is the 'orbiting effect', here is how i solved it (partially, failing at high speed moving objects)

```Local \$rat1x, \$rat1y ; ratio de vitesse x/y
Local \$rat2x, \$rat2y ; ratio de vitesse x/y
; ---
If \$hSprite1[\$_gSpr_SpeedX] = 0 Then
\$rat1x = 0
\$rat1y = 1
ElseIf \$hSprite1[\$_gSpr_SpeedY] = 0 Then
\$rat1x = 1
\$rat1y = 0
Else
\$rat1x = \$hSprite1[\$_gSpr_SpeedX] / (Abs(\$hSprite1[\$_gSpr_SpeedY]) + Abs(\$hSprite1[\$_gSpr_SpeedX]))
\$rat1y = \$hSprite1[\$_gSpr_SpeedY] / (Abs(\$hSprite1[\$_gSpr_SpeedY]) + Abs(\$hSprite1[\$_gSpr_SpeedX]))
EndIf
;ConsoleWrite(\$rat1x & " , " & \$rat1y & @CRLF)
; ---
If \$hSprite1[\$_gSpr_SpeedX] < 0 Then
\$rat1x = -1 * Abs(\$rat1x)
Else
\$rat1x = Abs(\$rat1x)
EndIf
If \$hSprite1[\$_gSpr_SpeedY] < 0 Then
\$rat1y = -1 * Abs(\$rat1y)
Else
\$rat1y = Abs(\$rat1y)
EndIf
; ---
; ---
If \$hSprite2[\$_gSpr_SpeedX] = 0 Then
\$rat2x = 0
\$rat2y = 1
ElseIf \$hSprite2[\$_gSpr_SpeedY] = 0 Then
\$rat2x = 1
\$rat2y = 0
Else
\$rat2x = \$hSprite2[\$_gSpr_SpeedX] / (Abs(\$hSprite2[\$_gSpr_SpeedY]) + Abs(\$hSprite2[\$_gSpr_SpeedX]))
\$rat2y = \$hSprite2[\$_gSpr_SpeedY] / (Abs(\$hSprite2[\$_gSpr_SpeedY]) + Abs(\$hSprite2[\$_gSpr_SpeedX]))
EndIf
;ConsoleWrite(\$rat2x & " , " & \$rat2y & @CRLF)
; ---
If \$hSprite2[\$_gSpr_SpeedX] < 0 Then
\$rat2x = -1 * Abs(\$rat2x)
Else
\$rat2x = Abs(\$rat2x)
EndIf
If \$hSprite2[\$_gSpr_SpeedY] < 0 Then
\$rat2y = -1 * Abs(\$rat2y)
Else
\$rat2y = Abs(\$rat2y)
EndIf
; ---
Local \$x = 0
Do
If \$hSprite1[\$_gSpr_Masse] > 0 Then
If \$hSprite1[\$_gSpr_PosX] > \$hSprite1[\$_gSpr_OriX] And _
\$hSprite1[\$_gSpr_PosY] > \$hSprite1[\$_gSpr_OriY] And _
\$hSprite1[\$_gSpr_PosX] < \$__GEng_WinW - \$hSprite1[\$_gSpr_OriX] And _
\$hSprite1[\$_gSpr_PosY] < \$__GEng_WinH - \$hSprite1[\$_gSpr_OriY] Then
\$hSprite1[\$_gSpr_PosX] += \$rat1x
\$hSprite1[\$_gSpr_PosY] += \$rat1y
EndIf
EndIf
If \$hSprite2[\$_gSpr_Masse] > 0 Then
If \$hSprite2[\$_gSpr_PosX] > \$hSprite2[\$_gSpr_OriX] And _
\$hSprite2[\$_gSpr_PosY] > \$hSprite2[\$_gSpr_OriY] And _
\$hSprite2[\$_gSpr_PosX] < \$__GEng_WinW - \$hSprite2[\$_gSpr_OriX] And _
\$hSprite2[\$_gSpr_PosY] < \$__GEng_WinH - \$hSprite2[\$_gSpr_OriY] Then
\$hSprite2[\$_gSpr_PosX] += \$rat2x
\$hSprite2[\$_gSpr_PosY] += \$rat2y
EndIf
EndIf
;ConsoleWrite(\$rat1x & " , " & \$rat1y & @CRLF)
;ConsoleWrite(\$rat2x & " , " & \$rat2y & @CRLF)
\$x += 1
;ConsoleWrite(" >>> " & \$x & @CRLF)
If \$x = 10 Then
;ConsoleWrite("Max!" & @CRLF)
ExitLoop
EndIf
Until Not _GEng_Sprite_Collision(\$hSprite1, \$hSprite2, 0) ; check collision between the sprites (recursive call)```

## Create an account

Register a new account

×

• Wiki

• Back

• Git