Samedi 10 Mai 2008
~ Les Comètes : Tracé de trajectoires ~
Menu
> Accueil

Programmation
> Algorithmes de tri
> Java

Réseaux Telecom
> Logiciel Vigie

Dossiers
> Trajectoire de comètes
> Gestion d'emploi du temps
> Tracking d'internautes
> Référencement
> Open Office
> Multi-agents dans les EIAH

Divers
> Album Photo
> Citations
> Recettes
> Bibliothèque
> Logiciels
> Mini-Annuaire

A propos
> Mon CV
> Me contacter
Recherche
Google
Sur ce site
Sur le web
Annonces
Accueil > Trajectoire de comètes > Tracé de trajectoires

Remarque importante : Ces fonctions utilisent la bibliothèque graphique définie précédemment.

  1. Introduction :

    L'objectif final étant de représenter la trajectoire des comètes dans leur plan de révolution (Coniques dont l'un des foyers est le soleil), nous devons adapter la bibliothèque graphique en conséquence. Nous nous sommes fixé plusieurs contraintes afin d'avoir des fonctions les plus générales possibles, permettant une grande liberté de choix et d'utilisation. Si au départ, celles ci se révèlent être assez compliquées, il est en réalité facile de les simplifier afin de les rendre fonctionnelles (cf. 4-d).
    Nous avons entre autre voulu :
    • Que la visualisation de la trajectoire soit la plus claire possible (tout en se permettant quelques options purement esthétiques qui améliorent le rendu final).
    • Pouvoir choisir de tracer la courbe en plein (c'est à dire en ligne continue), ou en point (cette deuxième option permettant également de visualiser la cinétique des comètes).
    • Ajouter de la couleur afin de pouvoir visualiser le sens de déplacement des comètes.
    • Etc...

  2. Définition des Outils :

    1. Définition des constantes :

      let Pi=4.*.atan(1.0);;

      #Pi : float = 3.14159265359

      Pi, nombre mathématique bien connu, est alors défini comme étant un flottant. La définition de cette constante permet ainsi d'alléger les programmes et de ne pas avoir à réécrire chaque fois un grand nombre de décimales approximatives.

    2. Définition des types :

      Le type plein_point permettant de paramétrer le type de tracé de la courbe(continu ou non).

      type plein_point=plein|point;;

      #Le type plein_point est défini.

      Le type foyer qui détermine, dans le cas d'une hyperbole, s'il faut tracer la partie de la courbe se trouvant à proximité du soleil ou l'autre partie.

      type foyer=soleil|autre;;

      #Le type foyer est défini.

      Le type conique qui correspond aux paramètres de la conique à tracer.

      type conique={e:float;p:float;aap:float};;

      #Le type conique est défini.

      Le type comète qui correspond à la trajectoire effective à tracer. {equ=équation de la conique (type conique) ; foyer= foyer à considérer (Cf type foyer ci dessus) }

      type comete={equ:conique;foyer:foyer};;

      #Le type comete est défini.

    3. Parcours sans limites d'un tableau

      La structure des tableaux en Caml (vect) se révèle très pratique à parcourir. Cependant il nous est impossible de dépasser la taille du tableau sans nous induire en erreur. Pour corriger cela, nous avons programmé une fonction qui recherche le nième élément d'un tableau sans se préoccuper de la taille de celui-ci (il faut cependant que cette taille soit non nulle).Tout se passe comme si l'on avait concaténé plusieurs fois le tableau afin d'en obtenir un de taille suffisante pour pouvoir renvoyer l'élément voulu.

      let n_element tableau n=let l=vect_length tableau in
                            tableau.(n-(l*(n/l)));;

      #n_element : 'a vect -> int -> 'a = <fun>

  3. Un peu d'esthétisme !!


    Pour améliorer la représentation finale de nos trajectoires, on peut colorier le fond d'écran. Pour cela, on utilise la fonction :

    let fond_ecran couleur=set_color couleur;
                           fill_rect 0 0 (size_x()) (size_y());
                           set_color black;;

    #fond_ecran : color -> unit = <fun>

    Afin d'avoir un rendu final plus agréable, il est possible de tracer des étoiles sur le fond d'écran. Les étoiles sont positionnées de façon purement aléatoire. Pour cela il convient d'ouvrir la bibliothèque " random ".

    #open "random";;

    Pour tracer les étoiles on utilise la fonction " etoiles " qui prend en argument le nombre d'étoiles et leur couleur.

    let etoiles nombre couleur=set_color couleur;
                       for i=1 to nombre do
                       point_ecr {X=(int (size_x()));Y=(int (size_y()))};done;
                       set_color black;;

    #etoiles : int -> color -> unit = <fun>

    La fonction " ciel ", quant à elle, prend en argument le nombre d'étoiles à tracer et un tableau de couleurs. Elle trace des étoiles de chaque couleur en nombre égal et de façon à ce que le nombre total soit celui voulu.

    let ciel n couleurs=let y=(vect_length couleurs) in
                        for i=0 to (y-1) do
                                etoiles (n/y) (couleurs.(i));done;;

    #ciel : int -> color vect -> unit = <fun>

    La fonction " ciel2 " ne prend plus en argument que le nombre d'étoiles à tracer. Elle les place et choisit leurs couleurs aléatoirement.

    let ciel2 n=for i=0 to n do etoiles 1 (rgb (int 255) (int 255) (int 255)) done;;

    #ciel2 : int -> unit = <fun>

    Il convient aussi de représenter notre soleil, astre ayant un rôle non négligeable dans notre modélisation puisqu'il est le centre du référentiel.
    Un trait rouge horizontal permet, de plus, de visualiser le plan de l'écliptique tandis qu'un demi-trait vertical (de même couleur) représente l'axe de rotation du soleil. Rq :cette fonction ne peut s'appeler soleil puisqu'il s'agit déjà d'un type (cf. II-2) .
    Cette fonction prend en argument le rayon du soleil et un repère.

    let astre_solaire rayon repère= set_color yellow;
                    fill_circle (repère.O.X) (repère.O.Y) (int_of_float((float_of_int(repère.I))*.rayon));
                             set_color red;
                             move_rep {x=(-.rayon);y=0.} repère;
                             line_rep {x=rayon;y=0.} repère;
                             move_rep {x=0.;y=(1./.2.)*.rayon} repère;
                             line_rep {x=0.;y=(1./.2.)*.(-.rayon)} repère;
                             set_color black;;

    #astre_solaire : float -> repere -> unit = <fun>

  4. Tracé des trajectoires

    1. Notion de sens de parcours de la trajectoire.

      En traçant la courbe avec des couleurs bien choisies on peut représenter le sens de parcours de la trajectoire. Pour cela il suffit de prendre une suite de couleurs qui ne forment pas un palindrome.
      Exemple :
      Soit la suite [....bleu, blanc, rouge, blanc, bleu, blanc, rouge, blanc...]. Cette suite forme un palindrome car on peut la lire indifféremment de la gauche vers la droite ou de la droite vers la gauche (la suite comporte des symétries). Une telle suite ne permet donc pas de déterminer un sens de lecture.
      Par contre la suite [...bleu, rouge, jaune, vert, bleu, rouge, jaune, vert, bleu, rouge, jaune, vert...] ne peut se lire dans les deux sens (la suite ne comporte pas de symétries).
      Le sens de lecture nous est donc imposé. Ainsi on peut déterminer un sens de déplacement suivant les couleurs.

    2. Tracé de coniques.

      Les coniques sont ici tracées à partir de leurs équations polaires.
      La fonction " color_conique " trace une conique en couleur à partir des paramètres qu'on lui définit.
      Elle reçoit en argument une comète, un repère, le paramètre plein ou point, le nombre de point à tracer (plus celui ci sera élevé, plus la résolution sera grande. 500 points donne déjà un résultat tout à fait satisfaisant, tant au niveau du rendu graphique que du temps d'exécution), un tableau de couleurs, l'angle minimal pour le tracé en polaire et la longueur de l'intervalle à tracer.

      let color_conique nom repere pp n tableau depart intervalle=
        let dt=(intervalle)/.(float_of_int n)
        and valeur p e teta aap=p/.(1.+.(e*.cos(teta-.aap)))
        and p=nom.equ.p and e=nom.equ.e and aap=nom.equ.aap in
        let t=ref(depart+.aap+.dt) in
        begin
        match pp with
        |plein ->set_color (n_element tableau 1);
                 move_rep {x=(valeur p e (!t) aap)*.cos(!t);y=(valeur p e (!t) aap)*.sin(!t)} repere;
                 for i=2 to n-1 do
                   t:=!t+.dt;
                   set_color (n_element tableau i);
                   line_rep {x=((valeur p e !t aap)*.cos(!t));y=((valeur p e !t aap)*.sin(!t))} repere;
                 done;
        |point ->for i=1 to n-1 do
                   set_color (n_element tableau i);
                   point_rep {x=((valeur p e !t aap)*.cos(!t));y=((valeur p e !t aap)*.sin(!t))} repere;
                   t:=!t+.dt;
                 done;
        end;
        set_color black;;

      #color_conique :.comete -> repere -> plein_point -> int -> color vect -> float -> float -> unit = <fun>

      On peut alors tracer les trajectoires de comètes de façon automatique. On utilise alors la fonction " trace_comete " qui compare les variables de la conique afin de choisir l'angle minimal et la longueur de l'intervalle. Dans le cas d'une hyperbole la fonction ne trace que l'une des deux branches (celle définie par le type foyer). " trace_comete " prend alors en argument une comète, un repère, le paramètre plein ou point, le nombre de point à calculer et un tableau de couleurs.

      let trace_comete nom repere pp n tableau=
      match (nom.equ.e) with
         |1.0->color_conique nom repere pp n tableau (-.Pi) (2.*.Pi)
         |x when x<.1. ->color_conique nom repere pp n tableau (0.) (2.*.Pi)
         |x ->let g=acos(-.1./.x) in
               match (nom.foyer) with
                 |soleil->color_conique nom repere pp n tableau (-.g) (2.*.g)
                 |autre->color_conique nom repere pp n tableau (g) ((2.*.Pi)-.(2.*.g));;

      #trace_comete : comete -> repere -> plein_point -> int -> color vect -> unit = <fun>

    3. Tracé de trajectoires

      Il ne reste plus qu'à définir une fonction " trajectoire " très simple qui prend en argument une comète, le paramètre plein ou point, le centre de l'écran et la largeur de la fenêtre (cette fonction utilisera la fonction " vision " afin d'avoir un repère orthonormal.) Remarque : Cette dernière fonction n'est en fait qu'une procédure combinant les fonctions précédentes. Il ne s'agit donc que d'une suggestion. Des dizaines d'autres procédures différentes pourraient être écrites. On peut d'ailleurs en écrire certaines qui traceraient plusieurs trajectoires.

      let trajectoire comète pp centre largeur=clear_graph();
      let repere=(vision centre largeur) in
      fond_ecran black;
      ciel 150 [|white;yellow;cyan|];
      trace_rep repere 1 blue;
      astre_solaire ((comète.equ.p)/.5.) repere;
      trace_comete comète repere pp 500 [|blue;white;red;yellow;magenta|];;

      #trajectoire : comete -> plein_point -> float * float -> float -> unit = <fun>

    4. Exemple:

      Nous allons tracer en exemple la trajectoire de la désormais célèbre comète de Halley. Il s'agit d'une comète d'excentricité proche de 1 (donc sa trajectoire est très allongée). Ses éléments orbitaux lors de son dernier passage en 1986 étaient : q=0.5871 ua ; e=0.9673 ;i=162.24° ; =58.14° ;=111.85° avec : q=distance au périhélie, e=excentricité, i=inclinaison orbitale, =longitude du noeud ascendant, =argument du périhélie. Pour représenter la trajectoire de la comète dans son plan de révolution on utilise donc simplement les paramètres q, e et . On a alors comète={equ={e=e; p=q*(1+e); aap=} ;foyer=soleil}.
      D'où :
      trajectoire {equ={e=0.9673;p=(0.5871*.1.9673);aap=(111.85*.Pi/.180.)};foyer=soleil} point (-.3.,-.20.) 65.;;
      - : unit = ()

    Les unités en abscisse sont en ua (unité astronomique=146.6 millions de km =distance moyenne terre/soleil).






    Agrandissement au voisinage du soleil.
    trajectoire equ={e=0.9673; p=(0.5871*.1.9673); aap=(111.85*.Pi/.180.)}; foyer=soleil} point (0.,-.2.) 8.;;
Accueil > Trajectoire de comètes > Tracé de trajectoires