Partage
  • Partager sur Facebook
  • Partager sur Twitter

La gravité

    26 avril 2016 à 12:57:34

    Bonjour (ou bonsoir),

    Donc, comme dit dans le titre, j'aimerais gérer la gravité mais d'une manière assez avancée et je n'arrive pas à trouver de moyen de le faire malgré m'être torturé l'esprit. D'ailleurs, je mets ce sujet dans le forum Java mais ce n'est pas tellement un problème de programmation, en effet, je pense que je pourrais assez simplement retranscrire ce qui est trouvé en lignes de code.

    Le problème est le suivant : J'aimerais pouvoir ajouter de la gravité, mais aussi gérer les collisions qui vont avec mais de manière pseudo réaliste, c'est à dire que lorsqu'un carré viens se poser sur le bord d'un autre objet, j'aimerais qu'il ne reste pas coincé bêtement en équilibre mais bien qu'il tombe en faisant une rotation, en gagnant de la vitesse sur un certain côté, ce qui lui fait faire d'autre rotation, etc ...
    On connaît la taille de l'objet (sa forme aussi, mais ce sera toujours un carré ou un rectangle), et la valeur de la gravité évidemment.

    Sur ce, bonne journée et merci d'avance aux personnes qui m'aideront.

    • Partager sur Facebook
    • Partager sur Twitter
    Apprenez, codez, dessinez, réfléchissez, ... L'important c'est d'aimer ce que l'on fait.
      26 avril 2016 à 13:31:00

      Hello!

      Les équations horaires peuvent peut être utiles.

      Par exemple, pour un mouvement rectiligne uniformément accéléré (cas typique d'une chute libre) les équations seront:

      a(t) = a0

      v(t) = a0*t + v0

      x(t) = (1/2)a0*t² + v0*t + x0

      où :    - a est l’accélération en m/s² (dans le cas d'une chute libre g = 9.81 à Paris)

                - v est la vitesse en m/s

                - x est la position

      Le 0 derrière renvoie à la valeur initiale (dans le cas d'une chute libre et en prenant pour position origine le point de départ de la chute, v0 = 0 et x0 = 0)

      Pour un mouvement de rotation uniformément accéléré:

      a(t) = a0

      w(t) = a0*w + w0

      θ(t) = (1/2)a0*w + w0*t + θ0

      ou : -a est l'accélération angulaire en rad/s²

             -w est la vitesse de rotation rad/s

             -θ est l'angle orienté en rad

      Il ne faut pas chercher à appréhender un solide en entier mais seulement des points dont les positions successives auront été déterminées. Ensuite il ne restera plus qu'à les relier.

      Les autres formules de cinématiques pourront aussi être utiles, mais là je laisse les recherches ouvertes.

      Après peut être que des API sont prévues pour gérer ce type de cas, mais là je ne m'y connais pas du tout.

      -
      Edité par -Nox 26 avril 2016 à 13:32:43

      • Partager sur Facebook
      • Partager sur Twitter
        26 avril 2016 à 13:36:42

        Salut,

        Pour ce faire il te faudra implémenter des équations de physique sur les mouvement d'objet, qui dépendent du temps. La variable temps sera celle qui déterminera a l'instant t la position des objets. Elle évoluera a chaque frame de ton application permettant ainsi de créer un mouvement. Pour la collision, il faudra évaluer la position/distance entre deux objets pour voir si ils sont en collision ou non.

        • Partager sur Facebook
        • Partager sur Twitter
          26 avril 2016 à 14:04:54

          Merci à vous deux pour vos réponse,

          -Nox, merci pour tes équations qui vont sans doute m'être utile. Il me reste néanmoins une question : comme tu l'as dit, il faut gérer chaque point puis ensuite les relier, et les points à gérer dans le cas de mon carré/rectangle sont les quatre points qui le définit ; ma question est comment gérer ces quatre points indépendamment et en même temps ajouter des contraintes pour que la structure de mon carré ne se déforme pas ? De plus, pour les collisions, qui sont un autre gros problème, j'ai absolument aucune idée de comment les gérer si on ne considère que les quatre points de mon carré (il pourrait se bloquer en passant au travers d'un objet alors que la collision des points fonctionne correctement). Aussi, pour les équations de rotation, si j'ai bien compris, on gère l'angle des points toujours indépendamment les uns des autres, sauf que leur rotation doit se faire par rapport à eux même, ou par rapport au centre du carré par exemple ?
          J'irais aussi voir du coté des formules de cinématiques pour voir ce qu'il en est.

          BabC, merci pour tes explications. Ce qu'il me manquait en grande majorité était justement ces équations. Et puis pour la collision, j'ai déjà fait des systèmes qui la gère, le seul problème est que, comme dit dans le post d'origine, si le carré arrive sur le bord de l'obstacle, il restera coincé à moitié en l'air.

          Quoiqu'il en soit, merci de vos réponses rapides :)

          -
          Edité par Mathiouza 26 avril 2016 à 16:18:41

          • Partager sur Facebook
          • Partager sur Twitter
          Apprenez, codez, dessinez, réfléchissez, ... L'important c'est d'aimer ce que l'on fait.
            26 avril 2016 à 23:14:16

            Une solution peut être de créer un objet Rectangle qui contiendrait cinq points; les quatre points de ton rectangle et son centre de gravité, ainsi qu'un vecteur qui représenterai l'orientation de ton rectangle (pour les rotations). Tes quatre points seraient contraints par rapport à ton centre de gravité et ton vecteur.

            Pour les collisions une solution mathématiquement viable peut être de vérifier si un des segments de ton rectangle croise celui d'au autre rectangle. Pour cela on peut considérer que cela se produit le point d'intersection des deux droites directrices de ces deux segments se situe sur un des deux segments.

            J'ai pris des notes pour réaliser un exemple, alors c'est un peu (beaucoup) fouillis. Je le met quand même mais si tu ne veut pas le lire ne te sens pas obliger surtout si ça t'embrouille.

            //DEBUT EXEMPLE

            Exemple: soit deux segments l'un défini par les points A(-2 ; 3), B(2; 2) et l'autre ; C(1 ; 2) D( -4; -5)

            Équation cartésienne de (AB) : (yB-yA)x - (xB - xA)y + c = 0

            (2 - 3)x - (2 + 2)y + c = 0

            -x - 4y + c = 0

            On remplace x et y par xA et xB:

            2 + 3*-4 + c = 0

            c = 10

            Équation de (AB) : -x - 4y + 10 = 0

            Par la même méthode:

            Équation de (CD) : -7x + 5y - 3 = 0

            On cherche le point d'intersection qui se trouve par la résolution d'un système d'équation:
            -x - 4y + 10 = 0
            -7x + 5y - 3 = 0

            ou

            -x - 4y = -10
            -7x + 5y = 3

            La résolution matricielle semble être la plus appropriée.
            -1  -4  = -10
            -7  5   = 3

            det = (-1 * 5) - (-7*-4) = -33
            x = ((-10 * 5) - (3*-4))/det = -38/-33
            y = ((-1 * 3) - (-7*-10))/det = -73/-33

            Point d'intersection (AB)(DC)  E(38/33 , 73/33)

            Si ((xE>=xA ET xE<=xB) OU (xE>=xB ET xE<=xA)) OU ((yE>=yA ET yE<=yB) OU (yE>=yB ET yE<=yA)) ALORS collision = true

            //FIN EXEMPLE


            Pour gérer les collisions tu peut utiliser ce code (il n'est pas opti mais semble fonctionner):

            public class Collision
            	{
            		double	x_inter, y_inter,
            		
            				aAB, bAB, cAB, aCD, bCD, cCD,
            				det_matrice;
            		boolean collision;
            		
            		Collision(double xA, double yA, double xB, double yB, double xC, double yC, double xD, double yD)
            		{
            			aAB = yB - yA;
            			bAB = -(xB - xA);
            			aCD = yD - yC;
            			bCD = -(xD - xC);
            			cAB = -(aAB * xA + bAB * yA);
            			cCD = -(aCD * xC + bCD * yC);
            
            			det_matrice = aAB * bCD - aCD * bAB;
            			x_inter = (-cAB * bCD + cCD * bAB) / det_matrice;
            			y_inter = (aAB * -cCD - aCD * -cAB) / det_matrice;
            			
            			System.out.println("x : " + x_inter + "y : " +y_inter);
            			
            			if(
            				(	((x_inter >= xA && x_inter <=xB) || (x_inter >= xB && x_inter <=xA)) &&
            			    	((y_inter >= yA && y_inter <=yB) || (y_inter >= yB && y_inter <=yA))	)
            			   &&
            			   	(	((x_inter >= xC && x_inter <=xD) || (x_inter >= xD && x_inter <=xC)) &&
            		    		((y_inter >= yC && y_inter <=yD) || (y_inter >= yD && y_inter <=yC))	)
            					
            			  ) 
            				collision = true;
            			else
            				collision = false;
            			
            			System.out.println(collision);
            		}
            		
            
            		public boolean getCollision(){
            			return collision;
            		}
            		public double getXInter(){
            			return x_inter;
            		}
            		public double getYInter(){
            			return y_inter;
            		}
            		
            	}


            Une fois que tu as vérifier si il y eu collision (méthode getCollision()), tu récupère les valeurs du point de collision. Tu les compare à la position de ton centre de gravité. Selon sa position relative tu ajuste l'orientation de ton rectangle (avec ton vecteur).

            Reste à gérer deux cas particuliers :

            - le cas ou ton rectangle tombe à plat sur un autre rectangle. (il faudra vérifier si les droites directrices des segments que tu compare ne soient pas confondues avant de les comparer) Si ce cas se produit il y aura toujours au moins deux segments orthogonaux entre tes deux rectangles, c'est avec eux que tu pourra gérer la position à adopter dans ce cas là.

            -le cas de la glissade, dans le cas ou ton rectangle tombe à plat sur un autre rectangle penché (il faudra alors faire varier la position de ton centre de gravité en abscisse également).

            N'hésite pas à nous faire part de tes avancées.

            • Partager sur Facebook
            • Partager sur Twitter
              27 avril 2016 à 15:07:55

              Tout ça peut vite devenir compliqué (d'expérience). Je te conseil plutôt d'utiliser de l'existant:

              Physics engine de google en java: https://github.com/google/liquidfun

              • Partager sur Facebook
              • Partager sur Twitter
                27 avril 2016 à 21:04:16

                Merci beaucoup -Nox pour ton aide très précieuse, je vais commencer à réfléchir dessus avec les informations que tu as apportées. Ne t'inquiète pas pour tes explications, elles me permettrons tout de même à comprendre un peu la logique derrière tout ça, histoire que j'expérimente un peu voir ce que ça donne. En dernier recourt, j'utiliserais ton code, mais j'aimerais essayer de faire ça moi-même en premier lieu : )

                tokazio, j'imagine bien que ça risque de se compliquer au fur et à mesure, mais justement, ce sera une fierté personnelle de réussir à faire ça sans prendre des choses déjà faites sur internet. Après, ça facilite évidemment les choses, et en dernier recourt, je l'utiliserais.

                Merci en tous cas à vous deux et je vous tiendrais au courant de l'avancée du projet : )

                • Partager sur Facebook
                • Partager sur Twitter
                Apprenez, codez, dessinez, réfléchissez, ... L'important c'est d'aimer ce que l'on fait.

                La gravité

                × 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