Partage
  • Partager sur Facebook
  • Partager sur Twitter

Rotation d'un vecteur en C

Problème dans de norme

    21 novembre 2017 à 19:54:31

    Bonjour/Bonsoir tout le monde,

    Je suis actuellement en L3 de physique et c'est la première année qu'on touche un peu à de la prog en C.
    Pour un projet, nous devons simuler le déplacement d'une bactérie qui possède 2 modes de déplacement :
    -Un mode où elle se déplace par grand saut en tournant à droite ou à gauche avec un petit angle.
    -Un mode où elle fait de petits sauts avec des angles plus grands.


    Pour l'instant, j'essaye de résoudre le problème sans prendre en compte la longueur des sauts, ils sont donc sensés être tous les mêmes. La proba de tourner à gauche ou à droite est 1/2. Il  y a également une possibilité à chaque pas de passer d'un mode à l'autre, que j'ai exprimé dans le programme (//passage d'un mode à l'autre).

    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    #include<time.h>
    
    
    
    int main() {
    	
    	//Variables
        	int N=15;
    	double theta;
    	int mode=1; //mode 1 = RUN mode 0 = TUMBLE
    	double x,y,xa,ya,dx,dy,xrot;
    	srand48(time(NULL));
            int i =0;
            
     
            if (drand48()>0.5)
                mode=0; //CHOIX ALEATOIRE DU MODE DE DEPLACEMENT
    
            x=0;y=0;xa=-1;ya=-1;
            
            while(i<N+1){
                
                //Passage d'un mode à l'autre
                if (mode==1 && drand48()<0.1) {
                    mode=0;
    
                }
                else if (mode==0 && drand48()>0.3) {
                    mode=1;
                }
                
                    if (mode==1) {
                        if (drand48()>0.5) //Proba de choix d'angle (rad)
    				theta = 0.13962634015955;
    			else
                                    theta = -0.13962634015955;
                    }
                    else {
                        if (drand48()>0.5) //Proba de choix d'angle
    				theta = 1.3962634015955;
    		    else
    				theta = -1.3962634015955;
    
                    }
                    
                            dx = x-xa;
                            dy = y-ya;
                            xa = x; 
                            ya = y;
                            x  = x+dx;
                            y  = y+dy;
                            xrot = x; //conserve la valeur de x pour la matrice de rotation 
    			x = x*cos(theta) - y*sin(theta);
    			y = xrot*sin(theta) + y*cos(theta); 
    			printf("%lf %lf %d %d\n",x,y,mode, i+1);
                    i++;
                    
            } //fin du while
    		
    		
    	
    	
    	
    	
    
    	return 0;
    }

    Comme vous pouvez le voir, le programme est assez simple, mon unique souci, c'est que dans le déroulement des choses, après avoir vérifié le mode (1 ou 0, qui fixe la valeur de l'angle), je "projette" mon vecteur dans la même directeur (à l'aide de dx et dy), puis j'utilise la matrice de rotation pour "tourner" mon vecteur si l'on veut.

    Le souci c'est que lorsque je fais une représentation graphique de la chose, les sauts n'ont absolument pas la même norme et j'ai l'impression que ça vient de mes opérations de rotation.
    Quelqu'un pourrait-il m'aiguiller ?

    Merci d'avance :)

    -
    Edité par RAVIOFR 21 novembre 2017 à 19:58:26

    • Partager sur Facebook
    • Partager sur Twitter
      21 novembre 2017 à 22:57:11

      Bonjour ! Je pourrais t'aider si tu donnes des indications sur ce que fais la programme, notamment le rôle des variables. Si j'ai bien compris, on choisit aléatoirement si on change de mode (avec une fonction que je ne connais pas, drand48), puis on choisit l'angle : une chance sur deux de choisir +80°, une chance sur deux de choisir -80°. C'est après que j'ai besoin de comprendre : la position courante, c'est (x, y) ou (xa, ya) ? En fait, je ne vois pas bien ce qu'est (xa, ya). Ni à quoi sert 'xrot' : c'est la module du vecteur ? Sûrement pas, puisque la ligne 55 choisit « xrot = x ». Et pourquoi n'y a-t-il pas de 'yrot' ? Bref, si tu m'éclaircit tout ça, je pourrais peut-être t'aider (la géométrie cartésienne, je connais).

      ----

      Ah, j'ai compris : (xa, ya), c'est l'ancienne position, la position à l'étape précédente ! ('a' comme ancien ! :) ) Bon, je regarde à nouveau...

      OK, j'ai trouvé l'erreur, je tape une explication...

      OK, donc :

      ‒ Lignes 49-50 : on calcule le dernier déplacement (écart entre la position courante et l'ancienne position.

      ‒ Lignes 51-52 : la position courante devient la (nouvelle) ancienne position.

      ‒ Lignes 53-54 : on re-calcule la position courante en la faisant avancer du même déplacement que la dernière fois. Pourqoui donc ? Ça veut dire que la (nouvelle) position courante s'obtient en faisant comme si on ne tournait pas ? À mon avis ces deux lignes ne doivent pas exister.

      ‒ Ligne 55 : ah, j'ai compris à quoi sert 'xrot' ! C'est parce que la ligne 56 va modifier x, or on a besoin du x non-modifié pour la ligne 57. Tu aurais dû utiliser xa et ya, plutôt. Même pas : c'est dx et dy qui doivent servir, en fait (voir plus loin).

      ‒ Lignes 56-57 : tu calcules la rotation par rapport à l'origine, voilà pourquoi c'est faux.

      Ce que tu dois faire, c'est :

      ‒ Calculer le dernier déplacement (OK).

      ‒ La position courante devient la (nouvelle) ancienne position (OK).

      ‒ Calculer les nouvelles valeurs de x et y avec la bonne formule (pas OK).

      Je crois que quelque chose comme ça doit marcher (mais je n'ai pas essayé) :

          dx = x-xa;  // dernier déplacement
          dy = y-ya;
          xa = x;     // la position courante est placée dans (xa, ya)
          ya = y;
          x = xa + dx*cos(theta) - dy*sin(theta); // rotation par rapport à la
          y = ya + dx*sin(theta) + dy*cos(theta); // position courante (xa, ya)
      

      -
      Edité par robun 21 novembre 2017 à 23:11:01

      • Partager sur Facebook
      • Partager sur Twitter
        22 novembre 2017 à 12:10:50

        Merci beaucoup pour ta réponse, je regarde ça quand je rentre et je te dis si j'arrive à faire fonctionner ça.

        sur le principe, je fais avancer la particule dans le meme sens que juste avantt, d'où les dx et dy, puis je fais mes rotations sur cette nouvelle position (x,y), j'ai du mal a voir pourquoi ces lignes ne doivent pas exister

        • Partager sur Facebook
        • Partager sur Twitter
          22 novembre 2017 à 12:29:24

          ravioli_gamer a écrit:

          sur le principe, je fais avancer la particule dans le meme sens que juste avantt, d'où les dx et dy, puis je fais mes rotations sur cette nouvelle position (x,y), j'ai du mal a voir pourquoi ces lignes ne doivent pas exister

          Tel que tu l'as programmée, ta rotation est une rotation d'angle theta et de centre l'origine qui agit sur le vecteur de coordonnés (x, y).

          Le calcul que j'ai mis fait, si je ne me suis pas trompé, une rotation d'angle theta et de centre (xa, ya) qui agit sur le vecteur de coordonnées (dx, dy). Ce n'est pas tout à fait la même chose que ce que tu as écrit (inutile de commencer à faire avancer la particuler dans le même sens que juste avant), mais il me semble que c'est la bonne méthode.

          • Partager sur Facebook
          • Partager sur Twitter
            22 novembre 2017 à 22:17:48

            J'ai ajusté mon programme, en traçant pour un nombre de sauts pas trop grand histoire de pouvoir bien voir les distances de sauts, j'obtiens enfin quelque chose d'un peu plus logique ! Je vais maintenant travailler sur le faire que les 2 modes font sauter plus ou moins loin la particule.

            Merci beaucoup en tout cas :D

            EDIT :

            Rien de très compliqué, il fallait juste rajouter un coefficient devant les dx et dy pour avoir des sauts plus ou moins long suivant le mode. le coeff est remis =1 au début de la boucle while et devient soit 4 soit 0.25 suivant le mode dans lequel on passe (ainsi, on a des sauts 4* plus petits en mode 0 que dans le mode 1).

            Voilà la représentation graphique du déplacement sur xmgrace :

            -
            Edité par RAVIOFR 22 novembre 2017 à 22:41:06

            • Partager sur Facebook
            • Partager sur Twitter
              23 novembre 2017 à 1:46:30

              Ah OK, l'amplitude du déplacement aussi est aléatoire, donc en effet c'est un peu plus compliqué que ce que j'avais proposé.

              C'est drôlement intéressant en tout cas !

              • Partager sur Facebook
              • Partager sur Twitter

              Rotation d'un vecteur en C

              × 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