Simaluteur planétaire
Publié : mar. 11/janv./2005 0:22
Salut,
Je me suis amusé à faire un simulateur de gravité dans lequel j'ai placé des planètes.
je leur ai donné une masse et une vitesse de départ.
Ensuite, le logiciel prend le relais grace à la loi de la gravité. j'obtients un système planétaire
Laissez les planètes éloignées faire plusieurs tours et vous allez voir le système plantéaire partir en vrac, c'est rigolo
Cette version n'est pas définitive, j'ai un problème de précision (quand 2 planètes sont trop proches, elle prennent des accélérations monstrueuses, il faut que je fasse tous mes calculs de gravité par intégration, vive les math et la bavasse)
Je me suis amusé à faire un simulateur de gravité dans lequel j'ai placé des planètes.
je leur ai donné une masse et une vitesse de départ.
Ensuite, le logiciel prend le relais grace à la loi de la gravité. j'obtients un système planétaire

Laissez les planètes éloignées faire plusieurs tours et vous allez voir le système plantéaire partir en vrac, c'est rigolo

Cette version n'est pas définitive, j'ai un problème de précision (quand 2 planètes sont trop proches, elle prennent des accélérations monstrueuses, il faut que je fasse tous mes calculs de gravité par intégration, vive les math et la bavasse)
Code : Tout sélectionner
Structure InfoGravite
ID.l
x.f
y.f
Vx.f
Vy.f
m.f
Etat.b
EndStructure
NewList Gravite.InfoGravite()
Procedure AddGravityObject(ID, x.f, y.f, Vitesse_X.f, Vitesse_Y.f, Masse.f, Etat.b)
AddElement(Gravite())
Gravite()\ID = ID
Gravite()\x = x
Gravite()\y = y
Gravite()\Vx = Vitesse_X
Gravite()\Vy = Vitesse_Y
Gravite()\m = Masse
Gravite()\Etat = Etat
EndProcedure
Procedure RemoveGravityObject()
DeleteElement(Gravite())
EndProcedure
Procedure GetGravityObjectPos(*Position.POINT)
*Position\x = Gravite()\x
*Position\y = Gravite()\y
EndProcedure
Procedure SetGravityObjectPos(*Position.POINT)
Gravite()\x = *Position\x
Gravite()\y = *Position\y
EndProcedure
Procedure.l GetGravityObjectID()
ProcedureReturn Gravite()\ID
EndProcedure
Procedure.l NextGravityObject()
ProcedureReturn NextElement(Gravite())
EndProcedure
Procedure MoveGravityObject()
ForEach Gravite()
*Objet.InfoGravite = @Gravite()
ForEach Gravite()
If *Objet <> @Gravite() ; Si on a un élément différent de celui sélectionné
; Calcul de la direction
Dx.f = (Gravite()\x - *Objet\x) ; Distance en X
Dy.f = (Gravite()\y - *Objet\y) ; Distance en y
D2.f = Dx * Dx + Dy * Dy ; Distance au carré
If D2 <> 0
D.f = Sqr(D2)
Dx = Dx / D ; Vecteur direction
Dy = Dy / D
; Calcul de la gravité et donc de l'évolution de la vitesse
; Gravité = k * Masse / Distance²
G1.f = *Objet\m / D2
G2.f = Gravite()\m / D2
*Objet\Vx + G2 * Dx
*Objet\Vy + G2 * Dy
Gravite()\Vx - G1 * Dx
Gravite()\Vy - G1 * Dy
EndIf
EndIf
Next
ChangeCurrentElement(Gravite(), *Objet)
Next
; On calcul les nouvelles positions
ForEach Gravite()
If Gravite()\Etat = 0
Gravite()\x + Gravite()\Vx ; On déplace l'objet
Gravite()\y + Gravite()\Vy
EndIf
Next
ResetList(Gravite())
EndProcedure
#Ecran_Largeur = 1024
#Ecran_Hauteur = 768
; On ouvre l'openscreen
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
MessageRequester("Erreur", "Impossible d'initialiser la souris ,le clavier ou l'écran. Vérifiez la présence de DirectX 7 ou supérieur.", 0)
End
EndIf
If OpenScreen(#Ecran_Largeur, #Ecran_Hauteur, 32, "Gravité") = 0
MessageRequester("Erreur", "Impossible d'ouvrir l'écran.", 0)
End
EndIf
CreateSprite(0, 5, 5)
StartDrawing(SpriteOutput(0))
Circle(2, 2, 2, $FFFFFF)
StopDrawing()
CreateSprite(1, #Ecran_Largeur, #Ecran_Hauteur)
; Pour ajouter des planète, c'est ici :
; AddGravityObject(ID, x.f, y.f, Vitesse_X.f, Vitesse_Y.f, Masse.f, Etat.b)
; ID : Identifiant de la planete
; x.f, y.f : Position de départ
; Vitesse_X.f, Vitesse_Y.f : Vitesse de départ
; Masse : mAsse de la planète (plus la planète est lourde et plus elle attire les autres
; Etat : Si = 1, la planète est fixe
AddGravityObject(0, 500, 350, 0, 0, 200, 0)
AddGravityObject(1, 200, 350, 0, 1, 10, 0)
AddGravityObject(2, 210, 350, 0, 0, 0.001, 0)
AddGravityObject(3, 800, 350, 0, -1, 10, 0)
AddGravityObject(4, 540, 350, 0, 3, 0.001, 0)
Repeat
ClearScreen(0, 0, 0)
; On lit les évènements clavier et souris
ExamineMouse()
ExamineKeyboard()
; Position de la souris
x = MouseX()
y = MouseY()
DisplaySprite(1, 0, 0)
MoveGravityObject()
While NextGravityObject()
GetGravityObjectPos(@Objet.POINT)
DisplaySprite(0, Objet\x - 2, Objet\y - 2)
; Traits des trajectoires
StartDrawing(SpriteOutput(1))
Box(Objet\x, Objet\y, 1, 1, $767676)
StopDrawing()
; Deboguage
StartDrawing(ScreenOutput())
Locate(0, 15 * GetGravityObjectID())
DrawText(Str(Objet\x) + ", " + Str(Objet\y))
StopDrawing()
Wend
FlipBuffers()
If IsScreenActive() = 0
End
EndIf
Until KeyboardPushed(#PB_Key_Escape)