Partage
  • Partager sur Facebook
  • Partager sur Twitter

Calculer l'attraction gravitationnelle

Calculer l'attraction gravitationnelle entre des planètes

    9 janvier 2018 à 21:39:36

    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

    • Partager sur Facebook
    • Partager sur Twitter
    Cordialement, l'homme qui te regarde par la fenêtre quand tu dors.
      20 janvier 2018 à 11:31:18

      Peux tu poster tout ton code. Le problème ne vient peut être pas de tes formules mais sans doute des ticks ou de n'importe quoi d'autres
      • Partager sur Facebook
      • Partager sur Twitter
      "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
        20 janvier 2018 à 17:40:15

        Si tu utilise des Newtons la gravité terrestre c'est 9,81N/m² il me semble :)
        • Partager sur Facebook
        • Partager sur Twitter
        Coding, Study, Repeat;
          20 janvier 2018 à 23:38:22

          La formule de la gravitation selon Newton est  {\displaystyle F_{A/B}=G\times {\frac {m_{A}.m_{B}}{d^{2}}}} 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;
          	}
          	
          }

          Si tu ne comprends pas quelque chose n'hésite pas

          -----------------------------------Modification 3-----------------------------

          Effectivement je confirme les résultats de jojos. Il y a un décallage 

          Orbite Keplerienne avec 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

          • Partager sur Facebook
          • Partager sur Twitter
          "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
            24 janvier 2018 à 15:03:31

            Sacul360 a écrit:

            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 ?

            Voici tout mon code: https://1drv.ms/f/s!Ak69-GxOpF6PxmofT958nxah3B8X

            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

            • Partager sur Facebook
            • Partager sur Twitter
            Cordialement, l'homme qui te regarde par la fenêtre quand tu dors.
              28 janvier 2018 à 4:04:16

              Bonjour jojos 

              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 

              • Partager sur Facebook
              • Partager sur Twitter
              "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
                28 janvier 2018 à 13:59:12

                Sacul360 a écrit:

                Bonjour jojos 

                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 :p

                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

                • Partager sur Facebook
                • Partager sur Twitter
                Cordialement, l'homme qui te regarde par la fenêtre quand tu dors.
                  29 janvier 2018 à 9:22:00

                  Merci pour ta réponse jojos mais avant d'aller plus loin j'ai besoin de te poser quelques questions pour mieux comprendre le cadre de ce projet 

                  -Réalises tu le projet tout seul ou en groupe ? Si non c'est donc toi qui à tout codé ? 

                  -Dans quelle cadre réalises tu ce projet dans un cadre scolaire pour ta première pro Système numérique  ou alors juste pour ton simple plaisir ?

                  Cordialement Sacul360

                  -
                  Edité par Sacul360 29 janvier 2018 à 9:44:32

                  • Partager sur Facebook
                  • Partager sur Twitter
                  "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
                    29 janvier 2018 à 10:04:27

                    Sacul360 a écrit:

                    Merci pour ta réponse jojos mais avant d'aller plus loin j'ai besoin de te poser quelques questions pour mieux comprendre le cadre de ce projet 

                    -Réalises tu le projet tout seul ou en groupe ? Si non c'est donc toi qui à tout codé ? 

                    -Dans quelle cadre réalises tu ce projet dans un cadre scolaire pour ta première pro Système numérique  ou alors juste pour ton simple plaisir ?

                    Cordialement Sacul360

                    -
                    Edité par Sacul360 il y a 19 minutes

                    Je réalise le projet tout seul et pour le simple plaisir, pour m’entraîner et apprendre à coder.

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Cordialement, l'homme qui te regarde par la fenêtre quand tu dors.
                      31 janvier 2018 à 11:01:54

                      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

                      • Partager sur Facebook
                      • Partager sur Twitter
                      "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
                        31 janvier 2018 à 12:49:56

                        Sacul360 a écrit:

                        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 

                        • Partager sur Facebook
                        • Partager sur Twitter
                        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.
                        • Editeur
                        • Markdown