So i did a program on python using pygame trying to reproduce this simulation https://www.youtube.com/watch?v=HEfHFsfGXjs&t=0s . It works but when the mass of the first moving cube goes over ~400kg the simulation struggles a lot when a lot of collisions occure in a short amount of time and the cubes just go through eachother.This is the code :
import pygame
import numpy as np
import random
import os
import math
import time
pygame.mixer.init()
pygame.font.init()
pygame.mixer.music.load(os.path.join('Assets','Click.mp3')) #clicking sound after each collision
pygame.mixer.music.set_volume(0.7)
b = 0
FPS = 60
L , H = 1000 , 800
BLANC = (255,255,255)
NOIR = (0,0,0)
BLEU = (0,0,255)
ROUGE = (255,0,0)
VELA = 0
VELB = -5
MA = 1
MB = 100**1 #the mass the the second cube, the one moving at the beginning
T = 0 #initialisation of the collision counter
a = 50*(MB/MA)
if a > 200 :
a = 200
POLICE = pygame.font.SysFont("monospace",15)
WIN = pygame.display.set_mode((L,H))
pygame.display.set_caption("TESTPHYSIQUE")
ABS = pygame.Rect(L/10, 0 , 10 , H-150)
ORD = pygame.Rect(L/10, H-150 , L , 10)
CUBEB = pygame.Rect(L-100-a, H-150-a , a , a)
CUBEA = pygame.Rect(2*L/5, H-150-50 , 50 , 50)
#unused pause function that doesnt resolve the problem
def pause(t) :
t = t*1e-3
g = time.time()
while time.time()<g+t :
{}
#function that computes the velocity of each cube after each collision
def calculvitesse() :
global VELA
global VELB
global T
if CUBEA.x + VELA +50 > CUBEB.x +VELB :
VELA,VELB = ((MA-MB)/(MA+MB))*VELA + (2*MB/(MA+MB))*VELB , ((MB-MA)/(MA+MB))*VELB + (2*MA/(MA+MB))*VELA
pygame.mixer.music.play()
T += 1
if CUBEA.x + VELA < ABS.x +10 :
VELA = - VELA
pygame.mixer.music.play()
T +=1
def deplacement() :
CUBEB.x += VELB
CUBEA.x += VELA
def dessin_onglet():
WIN.fill(NOIR)
pygame.draw.rect(WIN,BLANC, ABS)
pygame.draw.rect(WIN,BLANC, ORD)
pygame.draw.rect(WIN,ROUGE, CUBEA)
pygame.draw.rect(WIN,BLEU, CUBEB)
compteur_collisions = POLICE.render (str(T),1,BLANC)
WIN.blit(compteur_collisions,(600,100))
pygame.display.update()
def main():
global b
clock = pygame.time.Clock()
c = True
while c :
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
c = False
calculvitesse()
deplacement()
dessin_onglet()
pygame.quit()
if __name__ == "__main__":
main()
So i tried reudcing the variable FPS that limits well the number of frames per second. That did not solve anything. I even tried to implement a "pause" function to get the fps even lower than one. That did not solve the problem either