Page 1 sur 1

Collision_2D

Publié : mar. 01/juil./2008 5:06
par Huitbit
Hello, en parcourant la toile, je suis tombé sur un petit bijou !

http://d.krauss.free.fr/documents/Physi ... _chocs.htm

En ce moment, je le décortique et je compte bien l'enrichir !
(il y a une question à la fin :!: [résolu] )
Pour l'instant, une collision élastique entre deux corps de tailles et de masses différentes.
Ca à l'air tout bête, ben je me suis amusé à refaire les calculs(fallait bien vérifier :roll: ), je comprends mieux pourquoi on ne traite que du cas à une dimension !

Un exemple d'évidence qui m'était passée sous le nez : pour que deux corps se touchent, il faut qu'ils se rapprochent :roll: . En maths, ça se traduit en une ligne ! La dérivée de la distance séparant les centres est négative (c'est à dire que la distance diminue)

Code : Tout sélectionner

If (x1-x2)*(vx1-vx2)+(y1-y2)*(vy1-vy2)<0
Il faut que je le vérifie mais c'est ce qui me posait problème dans mon p'tit squash (collision supplémentaire détectée lorsque la balle repart = n'importe quoi !)

Code : Tout sélectionner

;collision_1
;auteur Huitbit
;pb v4.20
;*********************************
#largeur_ecran=1024
#hauteur_ecran=768

;boule n°1
#r_1=128
#m_1=4
x_1.f : y_1.f=100
x_1_centre.f=x_1+#r_1 : y_1_centre.f=y_1+#r_1
vx_1.f=4 : vy_1.f=2

;boule n°2
#r_2=16
#m_2=2
x_2.f=600 : y_2.f=300
x_2_centre.f=x_2+#r_2 : y_2_centre.f=y_2+#r_2
vx_2.f=-2 : vy_2.f=2

#d_carre=(#r_1+#r_2)*(#r_1+#r_2)
#beta=2.0*#m_2 /((#m_1+#m_2)*#d_carre)
alpha.f

test.s=""

Enumeration
  #spr_2
  #spr_1
EndEnumeration

Macro test_variation_distance(x1c,y1c,vx1,vy1,x2c,y2c,vx2,vy2)
If (x1c-x2c)*(vx1-vx2)+(y1c-y2c)*(vy1-vy2)<0
  test="Rapprochement"
Else
  test="Eloignement"
EndIf
EndMacro

Macro test_contact(x1c,y1c,vx1,vy1,x2c,y2c,vx2,vy2)
If (x1c-x2c)*(x1c-x2c)+(y1c-y2c)*(y1c-y2c)<=#d_carre  And test="Rapprochement"
  contact=1

  alpha=#beta*((x2c-x1c)*(vx2-vx1)+(y2c-y1c)*(vy2-vy1))
  vx1=vx1+alpha*(x2c-x1c)
  vy1=vy1+alpha*(y2c-y1c)
  vx2=vx2-alpha*#m_1/#m_2*(x2c-x1c)
  vy2=vy2-alpha*#m_1/#m_2*(y2c-y1c)
Else
  contact=0
EndIf
EndMacro

Macro test_bord_ecran(xc,yc,vx,vy,r)
If xc+r>#largeur_ecran Or xc<r
  vx=-vx
EndIf
If yc+r>#hauteur_ecran Or yc<r
  vy=-vy
EndIf
EndMacro

InitSprite()
InitKeyboard()
OpenWindow(0,0,0,#largeur_ecran,#hauteur_ecran,"Collision_2D",#PB_Window_ScreenCentered|#PB_Window_SystemMenu  )
OpenWindowedScreen(WindowID(0),0,0,#largeur_ecran,#hauteur_ecran,0,0,0)

CreateSprite(#spr_2,#r_2*2,#r_2*2)
StartDrawing(SpriteOutput(#spr_2))
DrawingMode(#PB_2DDrawing_Outlined)
Circle(#r_2,#r_2,#r_2,RGB(0,255,0))
Plot(#r_2,#r_2,RGB(255,255,255))
StopDrawing()

CreateSprite(#spr_1,#r_1*2,#r_1*2)
StartDrawing(SpriteOutput(#spr_1))
DrawingMode(#PB_2DDrawing_Outlined)
Circle(#r_1,#r_1,#r_1,RGB(255,0,0))
Plot(#r_1,#r_1,RGB(255,255,255))
StopDrawing()

Repeat
  
  Repeat
    Event = WindowEvent()      
    If  Event = #PB_Event_CloseWindow
      End 
    EndIf
  Until Event = 0
  
  x_1_centre=x_1_centre+vx_1
  y_1_centre=y_1_centre+vy_1
  x_2_centre=x_2_centre+vx_2
  y_2_centre=y_2_centre+vy_2
  
  test_variation_distance(x_1_centre,y_1_centre,vx_1,vy_1,x_2_centre,y_2_centre,vx_2,vy_2)
  test_contact(x_1_centre,y_1_centre,vx_1,vy_1,x_2_centre,y_2_centre,vx_2,vy_2)
  test_bord_ecran(x_1_centre,y_1_centre,vx_1,vy_1,#r_1)
  test_bord_ecran(x_2_centre,y_2_centre,vx_2,vy_2,#r_2)
  
  ClearScreen(RGB(0,0,0)) 
  DisplayTransparentSprite(#spr_1,x_1_centre-#r_1,y_1_centre-#r_1)
  DisplayTransparentSprite(#spr_2, x_2_centre-#r_2,y_2_centre-#r_2)
  StartDrawing(ScreenOutput())
  DrawText(0,0,test)
  StopDrawing()
  
  Delay(1)
  FlipBuffers() 
ForEver


Attention au piège, toutes les formules utilisent les centres des objets (pas les coordonnées des sprites !) :!:

Le contact peut-être amélioré puisque selon la vitesse les boules peuvent s'interpénétrer. En fait, il faudrait replacer les boules à la distance r1+r2 à chaque contact.

Question : Le résultat du code ci-dessous est-il normal ?

Code : Tout sélectionner

;boule n°1 
#r_1=128 
#m_1=4 
;boule n°2 
#r_2=16 
#m_2=2 

#d_carre=(#r_1+#r_2)*(#r_1+#r_2)

betabis.d=2*#m_2 /((#m_1+#m_2)*#d_carre)
Debug betabis
#beta=2*#m_2 /((#m_1+#m_2)*#d_carre)
Debug #beta
Hasta la vista !

Publié : mar. 01/juil./2008 6:10
par comtois
Sympa ton code :)

Oui le résultat est normal, il faut forcer le type flottant quelque part, en indiquant 2.0 par exemple.

Code : Tout sélectionner

;boule n°1
#r_1=128
#m_1=4
;boule n°2
#r_2=16
#m_2=2

#d_carre=(#r_1+#r_2)*(#r_1+#r_2)

betabis.d=2*#m_2 /((#m_1+#m_2)*#d_carre)
Debug betabis
#beta=2.0*#m_2 /((#m_1+#m_2)*#d_carre)
Debug #beta

Publié : mar. 01/juil./2008 8:37
par djes
Pfiou, je sais pas pourquoi les français sont toujours aussi compliqués!
Voilà un lien avec des exemples bien plus clairs, à mon avis, et surtout qui prennent en compte la simulation informatique : http://www.myphysicslab.com/index.html

Souvent, les matheux nous pondent de magnifiques formules, sans tenir compte du fait de nos limitations au niveau numérique, et surtout du fait que nous travaillons non pas sur des séries, mais de façon séquentielle. C'est à nous de tout "convertir", en gérant la fréquence de rafraichissement. Pas toujours évident!

Là je ne peux pas trop t'aider, ça fait longtemps que je ne me suis pas replongé dans les maths, ça ne me vient pas "instantanément"... Par contre, sur le forum anglais, tu as Psychophanta qui a fait des trucs extra dans ce domaine.

Publié : mar. 01/juil./2008 14:39
par Huitbit
Hello !

@Comtois
il faut forcer le type flottant
Merci !
C'est bon à savoir :D
(j'ai rectifié le code)

@djes
Un grand merci pour ce lien !
:P
C'est une mine d'or !
C'est vrai que la page que je propose est moins adaptée à l'informatique mais ce qui m'a décidé à l'exploiter c'est l'idée de la dérivée pour gérer l'éloignement et le rapprochement !
Il y a une situation non abordée dans les liens précédents que je compte traiter et qui pourra servir de moteur pour un petit jeu original et inédit !
Je détaillerai ça quand je l'aurai fait (ça sera la surprise :P )!

Hasta la vista !

[EDIT] @djes
Pfiou, je sais pas pourquoi les français sont toujours aussi compliqués!
J'ai jeté un oeil sur ton lien, c'est quasiment la même chose pour les calculs mais certains résultats sont parachutés, les français sont justes plus rigoureux ! :)
Cette rigueur donne plus de liberté puisque rien n'est caché ! Par contre ça donne plus de boulot :lol: