En ce moment, je m'amuse avec quelques modèles physiques issus de la mécanique du solide.
Voici une petite démo(sans prétention et sans commentaires

Laissez tourner la démo pour voir différentes situations!
La physique, c'est magique !

Imaginez un p'tit bonhomme suffisamment costaud (Chuck Norris ?

Quand il y aura beaucoup d'épisodes "Collision_2D", je ferai un récapitulatif des lois physiques utilisées si ça intéresse quelqu'un

Code : Tout sélectionner
;collision_2
;auteur Huitbit
;pb v4.20
;*********************************
Enumeration
#spr_decor
#spr_1
#spr_2
#systeme_isole
#chute_libre
#pendule_pesant
EndEnumeration
#largeur_ecran=1024
#hauteur_ecran=768
#g=0.5
#dt=1
;boule n°1
#r_1=32
#m_1=1
x_1.f =0: y_1.f=128-2*#r_1
x_1_centre.f=x_1+#r_1 : y_1_centre.f=y_1+#r_1
vx_1.f=2+Random(16): vy_1.f=0
;boule n°2
#r_2=128
#m_2=4
x_2.f=512 : y_2.f=256
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)
#J=0.5*#m_1*#r_1*#r_1+#m_1*#d_carre+0.5*#m_2*#r_2*#r_2
omega.f
test.s=""
contact.b=0
modele.b
nom_modele.s
temps_d_arret.w
angle1.f
angle2.f
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+1 And test="Rapprochement"
contact=1
If modele=#chute_libre
If x1c>x2c
angle1=ATan((y1c-y2c)/(x1c-x2c))
Else
angle1=ATan((y1c-y2c)/(x1c-x2c))+#PI
EndIf
x1c=x2c+(#r_1+#r_2)*Cos(angle1)
y1c=y2c+(#r_1+#r_2)*Sin(angle1)
omega=#m_1/#J*((x1c-x2c)*vy1-(y1c-y2c)*vx1)
EndIf
temps_d_arret=temps_d_arret+1
If temps_d_arret>300
contact=0
x1c=#r_1 : y1c=128-#r_1
vx1=2+Random(16): vy1=0
angle1=0
angle2=0
omega=0
temps_d_arret=0
EndIf
EndIf
EndMacro
Macro test_bord_ecran(xc,yc,vx,vy,r)
If modele=#chute_libre
If xc+r>#largeur_ecran Or xc<128+r
vx=-vx
EndIf
If yc+r>#hauteur_ecran-32 Or yc<r
vy=-vy
EndIf
EndIf
EndMacro
Macro choix_modele
If x_1_centre<128+#r_1
modele=#systeme_isole
nom_modele="système isolé"
Else
If contact=0
modele=#chute_libre
nom_modele="chute libre"
Else
modele=#pendule_pesant
nom_modele="pendule pesant"
EndIf
EndIf
EndMacro
InitSprite()
InitSprite3D()
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_decor, #largeur_ecran,#hauteur_ecran)
StartDrawing(SpriteOutput(#spr_decor))
LineXY(0,128,128,128,RGB(0,0,255))
LineXY(128,128,128,736,RGB(0,0,255))
LineXY(128,736,1024,736,RGB(0,0,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()
CreateSprite(#spr_2,#r_2*2,#r_2*2,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(#spr_2))
DrawingMode(#PB_2DDrawing_Outlined)
Circle(#r_2,#r_2,#r_2,RGB(0,255,0))
Line(#r_2,#r_2,#r_2,0,RGB(255,255,255))
StopDrawing()
CreateSprite3D(#spr_2,#spr_2)
Repeat
Repeat
Event = WindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
Until Event = 0
choix_modele
If modele=#systeme_isole
x_1_centre=x_1_centre+vx_1*#dt
EndIf
If modele=#chute_libre
vy_1=vy_1+#g*#dt
x_1_centre=x_1_centre+vx_1*#dt
y_1_centre=y_1_centre+vy_1*#dt
EndIf
If modele=#pendule_pesant
omega=omega+#m_1/#J*(x_1_centre-x_2_centre)*#g*#dt
angle1=angle1+omega*#dt
x_1_centre=x_2_centre+(#r_1+#r_2)*Cos(angle1)
y_1_centre=y_2_centre+(#r_1+#r_2)*Sin(angle1)
EndIf
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)
DisplaySprite(#spr_decor,0,0)
DisplayTransparentSprite(#spr_1,x_1_centre-#r_1,y_1_centre-#r_1)
Start3D()
angle2=angle2+omega
RotateSprite3D(#spr_2,angle2*180/#PI,0)
DisplaySprite3D(#spr_2,x_2_centre-#r_2,y_2_centre-#r_2)
Stop3D()
StartDrawing(ScreenOutput())
DrawText(0,20,"Modèle : "+nom_modele)
StopDrawing()
Delay(1)
FlipBuffers()
ForEver