Bonjour, j'ai un programme qui simule l'attraction gravitationnelle des planètes mais le problème c'est que les planètes n'ont pas une orbite normale elle se décalent un peu à chaque fois (sans doute du à un problème d’imprécision ?) et j'aimerais savoir comment calculer l'attraction gravitationnelle avec ce fonctionnement:
Le code ci-dessous est exécute pour CHAQUE planète à chaque tick donc si il y a 3 planète le code va calculer:
pour la planète 1 l'attraction de la planète 2 et 3 / pour la planète 2 l'attraction de la 1 et 3 / pour la planète 3 l'attraction de la 2 et 1 et ceci à chaque tick
Chaque planète a une masse et une position X et Y je calcule la distance avec
Racine carrée de (distanceX² + distanceY²) et ça me donne la distance en pixel pas de problème jusqu'ici.
Puis je fais ça et quelque chose ne va pas ici:
double force = otherMass/(distance*distance);
// otherMass = masse de la deuxième planète
System.out.println(force);
double angle = Math.atan2(distY, distX);
this.velX += force * Math.cos(angle); // Vitesse appliquée à la première planète
this.velY += force * Math.sin(angle);
Merci d'avance à ceux qui m'aideront !
- Edité par jojos38000 9 janvier 2018 à 21:41:00
Cordialement, l'homme qui te regarde par la fenêtre quand tu dors.
La formule de la gravitation selon Newton est où F est la force exercée du corps a vers le corps b (ou inversement)// où G est la constante gravitationnelle ( 6,6742×10-11 N·m2·kg−2 )// où ma et mb sont respectivement les masses des corps a et b // où d est la distance entre les corps //
La force est la même pour a et b (logique) et elle s'applique dans l'axe ab
Tu dois aussi calculer l'angle du vecteur par rapport à un axe commun à tous, et rajouté la nouvelle force comme tu l'as fait dans ton code
Je ne suis pas sur que ce soit très clair donc pour t'aider je vais coder moi aussi un simulateur gravitationnelle
Voilà mon simulateur, il marche bien sauf quand les planètes se rencontrent en un point elles s’expulsent ! Etrange...
Frame
package com.IHM;
import javax.swing.JFrame;
import com.Simulateur.Espace;
public class Frame extends JFrame{
private Pan pan;
private Espace space;
public static void main(String[] args) {
new Frame();
}
public Frame() {
this.setSize(500,500);
space = new Espace(5,getWidth(),getHeight());
pan = new Pan(space);
this.setTitle("Gravitation");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(pan);
this.setLocationRelativeTo(null);
this.setVisible(true);
while(true) {
for(int i = 0;i < 500;i++) {
space.simulat();
space.move();
}
pan.repaint();
for(int i = 0;i< space.getPlanetes().size();i++) {
System.out.println(space.getPlanetes().get(i).getX()+" "+space.getPlanetes().get(i).getY()+" "+space.getPlanetes().get(i).getMasse()+" "+space.getPlanetes().get(i).getVelX()+" "+space.getPlanetes().get(i).getVelY()+" "+i);
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Pan
package com.IHM;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
import com.Simulateur.Espace;
public class Pan extends JPanel{
private Espace space;
public Pan(Espace space) {
this.space = space;
}
public void paintComponent(Graphics g) {
// On remet à zéro l'écran
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
// On affiche les planètes
g.setColor(Color.CYAN);
for(int i = 0;i < space.getPlanetes().size();i++) {
g.fillOval((int)space.getPlanetes().get(i).getX(), (int)space.getPlanetes().get(i).getY(),(int) space.getPlanetes().get(i).getMasse(), (int)space.getPlanetes().get(i).getMasse());
}
// On affiche le centre de masse, le point de convergence des planètes
double centreMasseX = 0;
double centreMasseY = 0;
int masseTotale = 0;
for(int i = 0;i < space.getPlanetes().size();i++) {
centreMasseX+= space.getPlanetes().get(i).getX()*space.getPlanetes().get(i).getMasse();
centreMasseY+= space.getPlanetes().get(i).getY()*space.getPlanetes().get(i).getMasse();
masseTotale += space.getPlanetes().get(i).getMasse();
}
centreMasseX = centreMasseX/masseTotale;
centreMasseY = centreMasseY/masseTotale;
g.setColor(Color.RED);
g.fillRect((int) (centreMasseX-10), (int) (centreMasseY-10), 20, 20);
}
}
Espace
package com.Simulateur;
import java.util.ArrayList;
import com.Astre.Planete;
public class Espace {
private ArrayList<Planete> planetes;
private double g;
public Espace(int n,int width,int height) {
planetes = new ArrayList<Planete>();
for(int i =0;i < n;i++) {
planetes.add(new Planete((int)(Math.random()*width),(int)(Math.random()*height),(int)(Math.random()*60+10)));
}
g = 6.6742* Math.pow(10,-11);
}
public void simulat() {
for(int i =0;i < planetes.size();i++) { // On parcoure toute la liste des planetes
for(int j = 0;j < planetes.size();j++) {// On fait interagir chaque planete
if(i != j) { // On vérifie que ce n'est pas la même planète
double distX = planetes.get(j).getX()-planetes.get(i).getX();
double distY = planetes.get(j).getY()-planetes.get(i).getY();
double distance = Math.sqrt(distX*distX+distY*distY);
double angle = Math.atan2(distY, distX);
double force = gravitation(planetes.get(i).getMasse(),planetes.get(j).getMasse(),distance);
planetes.get(i).addVelX(Math.cos(angle)*force);
planetes.get(i).addVelY(Math.sin(angle)*force);
}
}
}
}
public double gravitation(int ma,int mb,double distance) {
return g*((ma*mb)/(distance*distance));
}
public void move() {
for(int i = 0; i<planetes.size();i++) {
planetes.get(i).move();
}
}
public ArrayList<Planete> getPlanetes() {
return planetes;
}
public void setPlanetes(ArrayList<Planete> planetes) {
this.planetes = planetes;
}
}
Effectivement je confirme les résultats de jojos. Il y a un décallage
Pour obtenir, cette orbite j'ai désactivé le nettoyage de l'écran donc tout les images se superposent, toutes les positions de la planète. L'orbite ne devrait pas être aussi gros c'est du à une perte de vitesse au fur et à mesure la planète à perdu de la vitesse, et réduit son orbit donc la grossis Vous pouvez aussi constater que le décallage n'est pas le même partout. En faite, l'orbite pivote N'est ce pas étrange ?
- Edité par Sacul360 21 janvier 2018 à 11:05:07
"Il y a 2 choses infinies : la bêtise humaine et l'univers. Pour ce qui est de l'univers je ne suis pas sûr" Albert Einstein
Pour obtenir, cette orbite j'ai désactivé le nettoyage de l'écran donc tout les images se superposent, toutes les positions de la planète. L'orbite ne devrait pas être aussi gros c'est du à une perte de vitesse au fur et à mesure la planète à perdu de la vitesse, et réduit son orbit donc la grossis Vous pouvez aussi constater que le décallage n'est pas le même partout. En faite, l'orbite pivote N'est ce pas étrange ?
- Edité par Sacul360 21 janvier 2018 à 11:05:07
Bonjour, merci de ton aide, donc le décalage n'est pas normal ?
C'est le projet je l'ai pris directement de mon workspace donc vous pouvez le mettre dans votre eclipse et voir par vous même. A savoir que sur cette version j'ai énormément améliorer l'orbite en mettant la distance au carrée pour améliorer la précision des calculs du coup le décalage est très faible mais au bout de quelques secondes / minutes on peut le voir
Sacul360, pourrais-tu me dire quelle méthode tu as utilisé pour tracer l'orbite des planètes stp ? Parce-que dans mon programme ça marche bien mais ma méthode prends beaucoup de performance GPU.
- Edité par jojos38000 24 janvier 2018 à 15:10:10
Cordialement, l'homme qui te regarde par la fenêtre quand tu dors.
J'ai examiné ton code et je dois dire que j'ai été surpris de la quantité de code ! Je m'attendais à moins, mais il y a certaines classes, fonctions ou morceaux de codes dont je ne comprend pas l'utilité
Je t'en fais donc ici une liste non-exhaustive :
-je ne comprend pas l'utilité de la classe assignID et surtout de ça fonction createNegativeID() Pourquoi attribué des id négatifs ?! Et pourquoi avoir un tableau des id déjà utilisés ? Pourquoi ne pas juste enregistrer le dernier id assigné et juste retourner id + 1. Et aussi pourquoi assignID n'est pas une class interne et anonyme
-Dans ObjectsTrail, je ne comprend pas pourquoi tu recrées l'image background au lieu de juste la charger une fois, de lui ajouter les étoiles, ensuite sache que l'objet graphics possède une fonction drawImage avec comme paramètre
g.drawImage(image, x, y, width, height, null);
La redimension de l'image ce fait automatiquement, il suffit d'indiquer l'image, ces coordonnées et la taille souhaitée sans avoir besoin de la recharger à chaque redimension de l'écran
-Je remarque aussi que le button faster dans la class sideMenu n'est pas initialisé
-Et pourquoi avoir choisi de mettre la fonction de gestion de la gravitation dans la class Player ?
-Et concernant les planètes fixes et donc les idées négatifs, ce qu'il est possible de faire est de créer une class PlaneteFixe est de rédéfinir les setVelX et setVelY pour les empêcher de modifier la vitesse de la PlaneteFixe, ce qui permet de ne pas s’embêter avec les id négatifs
-Et en dernier concernant le curseur de la souris, il est possible de définir l'image du curseur donc de ne pas utiliser une planète suiveuse du curseur et de supprimer l'id -273
Je me suis donc pencher sur votre fonction pour gérer la gravitation et je constate que vous utiliser une formule non-Newtonienne Pourquoi ?
Concernant le décalage, je n'ai toujours pas trouvé C'est assez étrange puisqu'il n'y a que l'apogée qui se réduit et non le périgée ?!
Il faut continuer d'étudier cela il doit y avoir une solution
Cordialement Sacul
PS : Je suis très admiratif de ce que tu as fait et ne prend pas mes remarques pour des critiques blessantes car elles n'en sont pas
"Il y a 2 choses infinies : la bêtise humaine et l'univers. Pour ce qui est de l'univers je ne suis pas sûr" Albert Einstein
J'ai examiné ton code et je dois dire que j'ai été surpris de la quantité de code ! Je m'attendais à moins, mais il y a certaines classes, fonctions ou morceaux de codes dont je ne comprend pas l'utilité
Je t'en fais donc ici une liste non-exhaustive :
-je ne comprend pas l'utilité de la classe assignID et surtout de ça fonction createNegativeID() Pourquoi attribué des id négatifs ?! Et pourquoi avoir un tableau des id déjà utilisés ? Pourquoi ne pas juste enregistrer le dernier id assigné et juste retourner id + 1. Et aussi pourquoi assignID n'est pas une class interne et anonyme
-Dans ObjectsTrail, je ne comprend pas pourquoi tu recrées l'image background au lieu de juste la charger une fois, de lui ajouter les étoiles, ensuite sache que l'objet graphics possède une fonction drawImage avec comme paramètre
g.drawImage(image, x, y, width, height, null);
La redimension de l'image ce fait automatiquement, il suffit d'indiquer l'image, ces coordonnées et la taille souhaitée sans avoir besoin de la recharger à chaque redimension de l'écran
-Je remarque aussi que le button faster dans la class sideMenu n'est pas initialisé
-Et pourquoi avoir choisi de mettre la fonction de gestion de la gravitation dans la class Player ?
-Et concernant les planètes fixes et donc les idées négatifs, ce qu'il est possible de faire est de créer une class PlaneteFixe est de rédéfinir les setVelX et setVelY pour les empêcher de modifier la vitesse de la PlaneteFixe, ce qui permet de ne pas s’embêter avec les id négatifs
-Et en dernier concernant le curseur de la souris, il est possible de définir l'image du curseur donc de ne pas utiliser une planète suiveuse du curseur et de supprimer l'id -273
Je me suis donc pencher sur votre fonction pour gérer la gravitation et je constate que vous utiliser une formule non-Newtonienne Pourquoi ?
Concernant le décalage, je n'ai toujours pas trouvé C'est assez étrange puisqu'il n'y a que l'apogée qui se réduit et non le périgée ?!
Il faut continuer d'étudier cela il doit y avoir une solution
Cordialement Sacul
PS : Je suis très admiratif de ce que tu as fait et ne prend pas mes remarques pour des critiques blessantes car elles n'en sont pas
Bonjour, merci beaucoup de ton aide je vais répondre pour chaque proposition dans l'ordre:
Pourquoi la classe assignID et assignNegativeID et pourquoi un tableau, le tableau sert à boucher les trous parce que en fait si j'assigne l'ID 1,2 et 3 et que la 2eme planète est supprimé ben la prochaine planète crée prendra automatiquement la place de la deuxième au lieu de laisser un trou et prendre la quatrième.
Quant-aux ID négatif ça me sert juste à définir si une planète est fixe ou pas (un soleil par exemple je vais lui assigner l'ID négatif et il ne sera pas affecté par les autres planètes il ne pourra pas bouger il sera fixe)
Dans ObjectTrail je sais pas comment faire ce que tu m'as expliqué j'ai pas trop compris ? Je veux optimiser au maximum cette fonction car elle fait beaucoup trop buguer le programme (très très gourmande en resource) donc si tu as des idées pour ne pas le redraw à chaque fois je suis preneur !
Par ailleurs j'ai utilisé la fonction g.drawImage dans la classe window. Je la redraw à chaque fois parceque sinon au repaint suivant elle disparait..
Le bouton faster n'est pas terminé, je le ferais plus tard
Pourquoi la gestion de la gravitation dans la classe Player ben je sais pas en fait, ça fonctionne donc je touche pas
Pour la planètes fixes justement c'est l'inverse je voulais pas recréer une classe parce-que c'était trop long et je perdais bien moins de temps à juste faire des ID négatifs (je suis assez nul en programmation hein mon code est très mal optimisé et assez mauvais)
Pour le curseur j'ai pas compris ton idée il faudrait m'expliquer en détail
Pour la gravitation je n'y connais rien j'ai utilisé cette fonction parce-qu'elle fonctionne si tu sais comment faire pour l'améliorer je suis preneur (c'était le but du sujet ^^)
Pour le décalage la seule solution que j'ai trouvé pour l'instant c'est de mettre la distance au carré.
- Edité par jojos38000 28 janvier 2018 à 14:05:05
Cordialement, l'homme qui te regarde par la fenêtre quand tu dors.
Ok après quelques testes regardes ce que j'ai obtenu ça
PS : Quand j'ai pris le screen l'orbite avait déjà fait 3 ou 4 tours donc c'est un phénomène stable
Mais tu vas me dire "What's the fuck ?!"
En faite dans mon simulateur je n'ai pas de décallage mais une rotation de l'orbite autour d'un axe
Voici un orbite normale
Au fur et à mesure l'orbite se met à tourner donc finalemen jusqu'à revenir à son point de départ
J'espère que tu as compris
Voici le même résultat sur ton simulateur
Mais il reste toujours un mystère : Pourquoi y a t il une rotation de l'orbite ?
Je pense que le mieux est de déplacer ce topicdans la catégorie physique
Cordialement Sacul360
PS : Pour ne pas attendre 3000 ans que les planètes fassent des centaines de tours, j'ai acceléré ton et mon simulateur en ne rafraichissant que l'écran tout les 80 ticks :
tickThread = new Thread(){
public void run(){
for(int i = 0;i < 80;i++) { // On fait 80 ticks puis on rafraichit l'écran
handler.tick(); // Tick le render qui lui même tick chaque planète
SideMenu.animationsTick(); // Tick les animations
}
JF.getContentPane().revalidate(); // Rafraichis
JF.getContentPane().repaint(); // Refraichis
fpsTimer++; // +1 à chaque tick pour savoir le nombre de FPS / secondes
}
};
PS2 Si tu ne comprends pas quelque chose n'hésite pas Et je te conseille de visualiser toi même le phénomène
- Edité par Sacul360 31 janvier 2018 à 11:04:03
"Il y a 2 choses infinies : la bêtise humaine et l'univers. Pour ce qui est de l'univers je ne suis pas sûr" Albert Einstein
Ok après quelques testes regardes ce que j'ai obtenu ça
PS : Quand j'ai pris le screen l'orbite avait déjà fait 3 ou 4 tours donc c'est un phénomène stable
Mais tu vas me dire "What's the fuck ?!"
En faite dans mon simulateur je n'ai pas de décallage mais une rotation de l'orbite autour d'un axe
Voici un orbite normale
Au fur et à mesure l'orbite se met à tourner donc finalemen jusqu'à revenir à son point de départ
J'espère que tu as compris
Voici le même résultat sur ton simulateur
Mais il reste toujours un mystère : Pourquoi y a t il une rotation de l'orbite ?
Je pense que le mieux est de déplacer ce topicdans la catégorie physique
Cordialement Sacul360
PS : Pour ne pas attendre 3000 ans que les planètes fassent des centaines de tours, j'ai acceléré ton et mon simulateur en ne rafraichissant que l'écran tout les 80 ticks :
tickThread = new Thread(){
public void run(){
for(int i = 0;i < 80;i++) { // On fait 80 ticks puis on rafraichit l'écran
handler.tick(); // Tick le render qui lui même tick chaque planète
SideMenu.animationsTick(); // Tick les animations
}
JF.getContentPane().revalidate(); // Rafraichis
JF.getContentPane().repaint(); // Refraichis
fpsTimer++; // +1 à chaque tick pour savoir le nombre de FPS / secondes
}
};
PS2 Si tu ne comprends pas quelque chose n'hésite pas Et je te conseille de visualiser toi même le phénomène
- Edité par Sacul360 il y a environ 1 heure
Ok merci je ferais ça
Cordialement, l'homme qui te regarde par la fenêtre quand tu dors.
Calculer l'attraction gravitationnelle
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.