Macros pour afficher des resolutions d'equations

Tout ce qui concerne l'utilisation ou l'installation d'Asymptote.

Modérateur: gdm_asy

Règles du forum
Merci d'éviter le style SMS dans vos messages et de penser à utiliser la fonction Recherche avant de poster un message. Pour joindre des fichiers à vos messages, consulter ce sujet.
> Penser à utiliser les balises Code pour poster du code.

Macros pour afficher des resolutions d'equations

Messagepar Romain Janvier » Mercredi 25 Août 2010, 14:03

Bonjour,

Voici des macros que j'ai fait l'annee derniere pour afficher la resolution d'equations ou d'inequations avec des fleches sur les cotés.

Image

Les macros:

Code: Tout sélectionner
/* debut */
import geometry;
unitsize(1cm);


/* format: {{membre1,membre2,transition_sur_fleches_laterales,
                             transition_fleche_milieu},...}
   interligne: ecart entre chaque ligne (en unitsize ?)
   decalhorizontal: decalage horizontal entre le membre le plus long et
                    le centre des elipses. (unite?)
   margehorizontale: decalage horizontal des fleches par rapport aux membres (unite?)
   margeverticale: decalage en dessus ou en dessous (unite?)
*/

void solveequation(string[][] l_texte,real interligne=1.5, real decalhorizontal=20, real margehorizontale=5, real margeverticale=5, string[] l_operateurs=new string[] {}) {
  pair milieu1;
  pair milieu2;
  real positionhorizontale;
  /* phase 1: placer les operateurs */
  object[] l_egals=new object[] {}; // labels se trouvant a la place des '=', des '>' ou '<'
  int nb_equations=l_texte.length; // nombre de lignes de la resolution
  for(int i=0; i<nb_equations;++i) {
    l_egals[i]=Label("$0$",(0,-i*interligne)); // on place des 0 la ou seront les operateurs
  } /* QUEST: pourquoi ne pas mettre directement l'operateur? */

  /* phase 2: placer les membres de l'equation */
  add(new void(frame f, transform t) {
  // liste des points pour aligner a droite et a gauche des =
  pair[] l_points_egal=new pair[] {};
  // labels correspondant aux membres
  object[] l_membres=new object[] {};
  real largmax=0; // la longeur du membre le plus long
  for(int i=0; i<nb_equations;++i) {
    l_points_egal[2i]=point(l_egals[i],SW,t);
    l_points_egal[2i+1]=point(l_egals[i],SE,t);
    milieu1=(l_points_egal[2i]+l_points_egal[2i+1])/2;
    if (l_operateurs.length>i) { // si on a defini des operateurs, on les met
      add(f,Label(l_operateurs[i],milieu1,0.7N,basealign));}
    else /* QUEST: ca sent un peu la bidouille ce 0.7N */
     { // sinon on met '='
      add(f,Label("$=$",milieu1,0.7N,basealign));
     }
    l_membres[2i]=Label(l_texte[i][0]); // membre gauche
    l_membres[2i+1]=Label(l_texte[i][1]); // membre droit
    // on met a jour la longeur max
    largmax=max(new real[] {largmax,size(l_membres[2i]).x,size(l_membres[2i+1]).x});
    add(f,Label(l_membres[2i],l_points_egal[2i],NW,basealign));
    add(f,Label(l_membres[2i+1],l_points_egal[2i+1],NE,basealign));
  }

  /* phase 3: on place les labels sur les fleches laterales */
  positionhorizontale=largmax+decalhorizontal+margehorizontale;
  for(int i=0; i<nb_equations-1;++i) {
    /* on test s'il y a un texte a mettre */
    if (l_texte[i].length>2 && l_texte[i][2]!="") {
      milieu1 =(l_points_egal[2i]+l_points_egal[2i+2])/2;
      milieu2 =(l_points_egal[2i+1]+l_points_egal[2i+3])/2;
      /* fleche droite */
      draw(f,(l_points_egal[2i+1]+(size(l_membres[2i+1]).x+margehorizontale,0)){E}..
       {SE}(milieu2+(positionhorizontale,size(l_egals[0]).y/2)){SW}..
       {W}(l_points_egal[2i+3]+(size(l_membres[2i+3]).x+margehorizontale,size(l_egals[0]).y)),ArcArrow);
      /* fleche gauche */
      draw(f,(l_points_egal[2i]+(-size(l_membres[2i]).x-margehorizontale,0)){W}..
       {SW}(milieu1+(-positionhorizontale,size(l_egals[0]).y/2)){SE}..
       {E}(l_points_egal[2i+2]+(-size(l_membres[2i+2]).x-margehorizontale,size(l_egals[0]).y)),ArcArrow);

      /* Pour mettre les textes lateraux,
         on fait un oval noir,
         puis un oval blanc moins grand.
         On peut surement faire mieux. */
      draw(l_texte[i][2],ellipse,
           inverse(t)*((l_points_egal[2i]+l_points_egal[2i+2])/2+(-positionhorizontale,size(l_egals[0]).y/2)),
           0.8,Fill(black));
      draw(l_texte[i][2],ellipse,
           inverse(t)*((l_points_egal[2i]+l_points_egal[2i+2])/2+(-positionhorizontale,size(l_egals[0]).y/2)),
           Fill(white));
      draw(l_texte[i][2],ellipse,
           inverse(t)*((l_points_egal[2i+1]+l_points_egal[2i+3])/2+(positionhorizontale,size(l_egals[0]).y/2)),
           0.8,Fill(black));
      draw(l_texte[i][2],ellipse,
           inverse(t)*((l_points_egal[2i+1]+l_points_egal[2i+3])/2+(positionhorizontale,size(l_egals[0]).y/2)),
           Fill(white));
      /* QUEST: pourquoi ce n'est pas draw(f,... */
    }
    else
    { // s'il n'y a pas de texte laterale, on fait une fleche entre l'operateur courant et le suivant.
      milieu1=(l_points_egal[2i]+l_points_egal[2i+1])/2;
      milieu2=(l_points_egal[2i+2]+l_points_egal[2i+3])/2;
      draw(f,(milieu1-(0,margeverticale))--
              milieu2+(0,size(l_egals[0]).y+margeverticale),
              Arrow);
      if (l_texte[i].length>3 && l_texte[i][3]!="") { // s'il y a un texte, on le rajoute.
       add(f,Label(l_texte[i][3],
           (milieu1+milieu2+(0,size(l_egals[0]).y))/2,
           2E));
      }
    }
  }
  }); //fin add
}



Le code des macros est assez attroce, mais j'ai pas mal bidouillé pour le faire, sans forcement tout comprendre. Si quelqu'un a une facon plus simple pour calculer les coordonnées d'une boite, ca m'interesse.

En gros, il faut donner une liste de listes de strings, qui ont le format {membre gauche, membre droit, texte coté, texte milieu}. Les membres sont ceux de l'equation à la ligne correspondant, le texte cote, c'est ce qu'on met sur les fleches laterales (x2; -5...) et texte milieu, c'est pour mettre sur la fleche du milieu. On peut ne pas mettre de texte sur les fleches.

La deuxieme liste, c'est les operateurs entre les membres. Il me semble qu'il est optionnel et dans ce cas on met des "=". Et le decalhorizontal, je ne sais plus ce que ca fait et j'ai la fleme de regarder dans mon code. Je crois que c'est pour le decalage des fleches sur les cotes.

Mais comme je l'ai dit, c'est tres artisanal. Ca meriterait d'etre grandement amelioré et epuré. J'aimerai bien faire la meme chose, mais pour des tableaux de proportionnalite.

Et je vais essayer de faire un programme python qui prend l'equation et crache tout seul la resolution avec les etapes intermediaires. Mais c'est pas pour tout de suite.
Dernière édition par Romain Janvier le Jeudi 26 Août 2010, 14:02, édité 1 fois.
Romain Janvier
Kilo-utilisateur
 
Messages: 146
Inscription: Lundi 23 Août 2010, 13:57
Statut actuel: Actif et salarié | Enseignant

Publicité

Re: Macros pour afficher des resolutions d'equations

Messagepar chellier » Mercredi 25 Août 2010, 20:38

Romain Janvier a écrit:Le code des macros est assez atroce

Euh... non, non :roll: :)

Bon, c'est vrai que c'est pas simple. Je ne vais pas essayer de regarder de trop près le code (sinon je vais prendre mal à la tête).
Qu'appelles-tu "coordonnées des boites" ? Il faut juste le centre non ?

Je donne un exemple de ce que j'avais fait avec l'aide d'un exemple de la galerie de GM. Ce sera plus simple pour ceux qui suivraient le fil et je crois que l'idée est la même :
Code: Tout sélectionner
unitsize(1cm);

usepackage("amsmath");
usepackage("amsfonts");
usepackage("amssymb");

pair z0=(-1.75,0), z1=(1.75,0), z2=(0,1), z3=(0,-1);

object boite1=draw("$x < 5$",box,z2,invisible);
object boite2=draw("$\times (-2)$",ellipse,z0);
object boite3=draw("$\times (-2)$",ellipse,z1);
object boite4=draw("$\quad\dots\quad$",box,z3,invisible);

add(new void(picture pic, transform t) {
    draw(pic,point(boite1,W,t){W}..{S}point(boite2,N,t));
    draw(pic,point(boite2,S,t){S}..{E}point(boite4,NW,t),Arrow);
    draw(pic,point(boite1,E,t){E}..{S}point(boite3,N,t));
    draw(pic,point(boite3,S,t){S}..{W}point(boite4,NE,t),Arrow);
});

boite.png
boite.png (12.43 Kio) Vu 613 fois

Christophe
chellier
Modérateur
 
Messages: 355
Inscription: Samedi 25 Juillet 2009, 11:25
Localisation: Le Creusot
Statut actuel: Actif et salarié | Enseignant

Re: Macros pour afficher des resolutions d'equations

Messagepar Romain Janvier » Jeudi 26 Août 2010, 08:58

C'est ce dont je me suis inspiré pour mes macros.

Mais le probleme, c'est que je ne peux pas deviner à l'avance la position des annotations sur les fleches.

En tout cas j'aime bien la forme de tes fleches dans ton exemple. Il faudrait que je reprenne mon code, mais je ne sais pas si j'aurai le temps d'ici la rentrée.

Edit:
J'ai mis à jour mon code en le commentant un peu mieux et en rajoutant quelques variables pour simplifier la lecture.

Mais il y a des trucs bizarres. J'ai mis des commentaires avec "QUEST:" pour indiquer mes interogations. Il faut dire que j'avais beaucoup bidouillé pour arriver à ce resultat et que j'ai un peu du mal à comprendre ce que fait ce "add( new void(frame ..."
Romain Janvier
Kilo-utilisateur
 
Messages: 146
Inscription: Lundi 23 Août 2010, 13:57
Statut actuel: Actif et salarié | Enseignant


Retourner vers Asymptote

 


  • Articles en relation
    Réponses
    Vus
    Dernier message

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 2 invités