Tableau de proportionnalité et PGCD

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.

Tableau de proportionnalité et PGCD

Messagepar Romain Janvier » Mardi 11 Janvier 2011, 13:52

Bonjour,

Comme j'en ai parlé sur le forum LaTeX, voici mon fichier permettant d'afficher des tableau de proportionnalité, des produits en croix et des pgcd avec la méthode d'Euclide. C'est un peu brouillon, mais c'est parce que je les modifie au fur et à mesure.

Voici le code de tableau_proport.asy

Code: Tout sélectionner
/* debut */
import geometry;

struct Texte {
 string texte; // le texte
 object obj;   // l'objet obtenu en affichant le texte
 pair size;    // (longueur,hauteur) de l'objet
 pair min;     // coin inferieur gauche de l'objet
 pair max;     // coin superieur droit de l'objet
 pen ptexte;   // pen pour le texte
 static Texte Texte(string texte,real echelle=1cm,pen ptexte=currentpen) {
   Texte T=new Texte;
   T.texte=texte;
   T.obj=Label(baseline(texte),ptexte);
   picture tmp;
   add(tmp,T.obj);
   T.size=size(tmp)/echelle;
   T.min=min(tmp)/echelle;
   T.max=max(tmp)/echelle;
   T.ptexte=ptexte;
   return T;
 };

};

object operator cast(Texte T) {
return T.obj;
};

pair operator cast(Texte T) {
return T.size;
};

from Texte unravel Texte;

typedef string[][] tableau;

struct Fleche {
 string texte;  // le texte sur la fleche
 pair origine;  // la case de depart
 pair destination;  // la case d'arrivee
 pair direction1;   // direction de depart
 pair direction2;   // direction d'arrivee
 pair offseto;  // decalage du depart
 pair offsetd;  // decalage de l'arrivee
 pair offsett;  // decalage du texte
 arrowbar pointe; // type de fleche
 pen penfleche; // pen pour la fleche
 pen pentexte; // pen du texte
 pen penovale; //pen de l'ovale

 static Fleche Fleche(string texte, pair origine, pair destination, pair direction1, pair direction2=-direction1,pair offseto=(0,0), pair offsetd=(0,0), pair offsett=(0,0),arrowbar pointe=ArcArrow,pen penfleche=currentpen,pen pentexte=currentpen,pen penovale=currentpen) {
   Fleche F=new Fleche;
   F.texte=texte;
   F.origine=origine;
   F.destination=destination;
   F.direction1=direction1;
   F.direction2=direction2;
   F.offseto=offseto;
   F.offsetd=offsetd;
   F.offsett=offsett;
   F.pointe=pointe;
   F.penfleche=penfleche;
   F.pentexte=pentexte;
   F.penovale=penovale;
   return F;
 };

};
from Fleche unravel Fleche;

// Plaque la direction sur la direction N, S, E ou W la plus proche.
// Si la direction est un des bissectrices, alors on ajoute les deux
// direction les plus proches.
pair posfleche(pair direction) {
  pair res=(0,0);
  real r=degrees(direction);
  if ((r<=45) || (r>=315)) {
    res+=(1,0);
  };
  if ((r>=45) && (r<=135)) {
    res+=(0,1);
  };
  if ((r>=135) && (r<=225)) {
    res+=(-1,0);
  };
   if ((r>=225) && (r<=315)) {
    res+=(0,-1);
  };
  return res;
};

// Retourne le point obtenu en se placant dans un cadre dont mes points
// extremes sont min et max, en utilisant les valeurs de decal comme
// position relative.
// Si decal=(0,0), c'est le milieu
// Si decal=(1,1), coin superieur droit
// Si decal=(-1,-1), coin inferieur gauche...
pair positionrelative(pair decalage, pair min, pair max)
{
  real x=0, y=0;
  if (decalage.x>0) {
     x=decalage.x*max.x;
  } else {
     x=-decalage.x*min.x;
  };
  if (decalage.y>0) {
     y=decalage.y*max.y;
  } else {
     y=-decalage.y*min.y;
  };
  return (x,y);
}

// affiche tableau cree le tableau avec les fleches
// Tableau T : le texte du tableau
// Fleche[] LF : liste des fleches a placer ;
//               les coordonnees (i,j) correspondent a la colonne i
//               et la ligne j, en comptant a partir de 0
// Fleche[] LF2 : liste de fleches a placer dans le tableau
// pair P : Coin superieur gauche du tableau (pas encore utilisé)
// bool regulier : toutes les colonnes a partir de la 2e ont la meme taille
// real largmin : largeur minimum des colonnes a partir de la 2e
// real hautmin : hauteur minimum des lignes
// real margehoriz : marge horizontale autour des textes
// real margevertic : marge verticale autour des textes
// bool ellipse : trace les ellipses ou pas
void affichetableau(tableau T,Fleche[] LF=new Fleche[],Fleche[] LF2=new Fleche[],pair P=(0,0),bool regulier=false, real largmin=0, real hautmin=0,real margehoriz=0.05, real margevertic=0.05,bool ellipse=true){
  Texte[][] textes;
  int lignes=0, colonnes=T.length; // nombre de lignes et de colonnes
  real[] largeurs; // largeur des colonnes
  real[] hauteurs; // hauteur des lignes
  real hauteurtotale=0;
  real largeurmax=largmin;
  // on calcule les tailles des labels
  for(int i=0; i< T.length; ++i) {
    string[] TT=T[i];
    textes[i]=new Texte[];
    if (lignes<TT.length) {
      lignes=TT.length;
    };
    hauteurs[i]=hautmin;
    for(int j=0; j< TT.length; ++j) {
       //write("i="+(string)i+" j="+(string)j);
       if(largeurs.length<j+1) {
          //write("on initialise");
          largeurs[j]=largmin;
       };
       //write((string)i+","+(string)j);
       Texte txt=Texte(TT[j]);
       textes[i][j]=txt;
       if(txt.size.y>hauteurs[i]) {
         hauteurs[i]=txt.size.y;
       };
       if(txt.size.x>largeurs[j]) {
         //write("on met a jour");
         largeurs[j]=txt.size.x;
         if ((txt.size.x > largeurmax) && (j>0)) {
           ////write("on update");
           largeurmax=txt.size.x;
         };
       };
      //write(largeurs[j]);
    };
    hauteurtotale+=hauteurs[i]+2margevertic;
  };
  //write(largeurmax);
  real larg=largeurmax;
  real h=0;
  pair[][] listepos;
  // on affiche
  for(int i=0; i< T.length; ++i) {
     h-=hauteurs[i]/2+margevertic;
     string[] TT=T[i];
     listepos[i]=new pair[];
     real l=0;
     for(int j=0; j< TT.length; ++j) {
       //write("i="+(string)i+" j="+(string)j+" larg="+(string)larg);
       if (i==0) {
         draw((l,0)--(l,-hauteurtotale));
       };
       if ((j==0) || (!regulier)) {
          //write("larg="+(string)largeurs[j]);
          larg=largeurs[j];
       };
       l+=larg/2+margehoriz;
       listepos[i][j]=(l,h);
       //write("(l,h)="+(string)listepos[i][j]);
       add(textes[i][j],(l,h));
       l+=larg/2+margehoriz;
       larg=largeurmax;
     };
     if (i==0) {
       draw((0,0)--(l,0));
       draw((l,0)--(l,-hauteurtotale));
     };
     h-=hauteurs[i]/2+margevertic;
     draw((0,h)--(l,h));
  };
  // on s'occupe des fleches avec les ellipses
  for(Fleche F : LF) {
    pair d1=F.direction1;
    pair d2=F.direction2;
    pair p1=F.origine;
    pair p2=F.destination;
    pair v1=posfleche(d1);
    pair v2=posfleche(-d2);
    pair pt1=(v1.x*(largeurs[floor(p1.x)]/2+margehoriz),v1.y*(hauteurs[floor(p1.y)]/2+margevertic))+listepos[floor(p1.y)][floor(p1.x)]+F.offseto;
    pair pt2=(v2.x*(largeurs[floor(p2.x)]/2+margehoriz),v2.y*(hauteurs[floor(p2.y)]/2+margevertic))+listepos[floor(p2.y)][floor(p2.x)]+F.offsetd;
    path fleche=pt1..controls pt1+d1 and pt2-d2..pt2;
    //path fleche=pt1{d1}..{d2}pt2;
    draw(fleche,F.penfleche,F.pointe);
    if (ellipse) {
       draw(Label(F.texte,F.pentexte),ellipse,midpoint(fleche)+F.offsett,F.penovale,FillDraw(fillpen=white));
    } else {
       label(F.texte,midpoint(fleche),F.offsett,F.pentexte);
    };
  };
  // on s'occupe des fleches pour les produits en croix
  for(Fleche F : LF2) {
    pair d1=F.direction1;
    pair d2=F.direction2;
    int xo=floor(F.origine.x);
    int yo=floor(F.origine.y);
    int xd=floor(F.destination.x);
    int yd=floor(F.destination.y);
    pair p1=listepos[yo][xo];
    pair p2=listepos[yd][xd];
    Texte t1=textes[yo][xo];
    Texte t2=textes[yd][xd];
    pair pt1=p1+positionrelative(d1,t1.min,t1.max)+F.offseto;
    pair pt2=p2+positionrelative(d2,t2.min,t2.max)+F.offsetd;
    path fleche=pt1--pt2;
    draw(fleche,F.penfleche,F.pointe);
  };

};


//tableau tutu = {{"Nombre de stylos","$1$","$2$","$5$"},{"Prix en euros et en francs aussi","$1,5$","$3$","$7,5$"}};
//Fleche F1=Fleche("$\times2$",(1,0),(2,0),N);
//Fleche F4=Fleche("$\times5$",(1,0),(3,0),2N,offseto=(-0.2,0));
//Fleche F2=Fleche("$\times5$",(1,1),(3,1),S);
//Fleche F3=Fleche("$\times1,5$",(3,0),(3,1),E,offseto=(0,-0.1),offsetd=(0,0.1),offsett=(0.2,0));
//Fleche F5=Fleche("$:1,5$",(3,1),(3,0),3E,offseto=(0,-0.2),offsetd=(0,+0.2));

//Fleche Bob=Fleche("",(0,0),(1,1),SE,NW,Arrows);
//affichetableau(tutu,new Fleche[] {F4,F5,F2,F3,F1},new Fleche[] {Bob},true,largmin=1);


// affichepgcd affiche la methode d'euclide en rajoutant des fleches
// nb1 : premier nombre de depart
// nb2 : second nombre
// Tableau T : le texte du tableau
// aff : indique si on doit afficher le texte correspondant
// afffleche : false si on ne doit jamais afficher les fleches
// incomplet : indique la longueur des dots a mettre
//             si on remplace les vals dans les pgcd par des dots
// real largmin : largeur minimum des colonnes
// real hautmin : hauteur minimum des lignes
// real margehoriz : marge horizontale autour des textes
// real margevertic : marge verticale autour des textes
void affichepgcd(int nb1, int nb2,int[][] aff=new int[][], bool afffleches=true, real incomplet=0, real largmin=0, real hautmin=1,real margehoriz=0, real margevertic=0.05){
  Texte[][] textes;
  tableau T;
  int n1=max(nb1,nb2);
  int n2=min(nb1,nb2);
  int q=quotient(n1,n2);
  int r=n1%n2;
  while (r>0) {
    string pgcd1=(incomplet>0) ? "\dfill{"+(string)incomplet+"cm}" :
                                 (string)n1+";"+(string)n2;
    string pgcd2=(incomplet>0) ? "\dfill{"+(string)incomplet+"cm}" :
                                 (string)n2+";"+(string)r;
    T[T.length]=new string[] {"$"+(string)n1+"$","$=$",
                              "$"+(string)q+"$","$\times$",
                              "$"+(string)n2+"$","$+$","$"+(string)r+"$",
                              "\;d'o\`u PGCD$("+pgcd1+
                              ")=\text{PGCD}("+pgcd2+")$"};
    n1=n2;
    n2=r;
    q=quotient(n1,n2);
    r=n1%n2;
  };
    string pgcd1=(incomplet>0) ? "\dfill{"+(string)incomplet+"cm}" :
                                 (string)n1+";"+(string)n2;
    string pgcd2=(incomplet>0) ? "\ldots" : (string)n2;
    T[T.length]=new string[] {"$"+(string)n1+"$","$=$",
                              "$"+(string)q+"$","$\times$",
                              "$"+(string)n2+"$","$+$","$"+(string)r+"$",
                              "\;d'o\`u PGCD$("+pgcd1+
                              ")="+pgcd2+"$"};
  int lignes=0, colonnes=T.length; // nombre de lignes et de colonnes
  int defaut=0; //pour completer les infos d'affichage
  if (aff.length==0) {
     defaut=1; // si aff est nul, on affiche tout
  };
  for (int i=0;i<aff.length;++i) {
    for (int j=aff[i].length;j<8;++j) {
      aff[i][j]=defaut;
    };
  };
  if (aff.length<colonnes) {
    for (int i=aff.length;i<colonnes;++i) {
       aff[i]=new int[] {defaut,defaut,defaut,defaut,defaut,defaut,defaut,defaut};
    };
  };
  real[] largeurs; // largeur des colonnes
  real[] hauteurs; // hauteur des lignes
  real hauteurtotale=0;
  real largeurmax=largmin;
  // on calcule les tailles des labels
  for(int i=0; i< T.length; ++i) {
    string[] TT=T[i];
    textes[i]=new Texte[];
    if (lignes<TT.length) {
      lignes=TT.length;
    };
    hauteurs[i]=hautmin;
    pen ptxt=black;
    for(int j=0; j< TT.length; ++j) {
       //write("i="+(string)i+" j="+(string)j);
       if(largeurs.length<j+1) {
          //write("on initialise");
          largeurs[j]=largmin;
       };
       //write((string)i+","+(string)j);
       ptxt=(aff[i][j]==1) ? black : white;
       Texte txt=Texte(TT[j],ptxt);
       textes[i][j]=txt;
       if(txt.size.y>hauteurs[i]) {
         hauteurs[i]=txt.size.y;
       };
       if(txt.size.x>largeurs[j]) {
         //write("on met a jour");
         largeurs[j]=txt.size.x;
         if ((txt.size.x > largeurmax) && (j>0)) {
           ////write("on update");
           largeurmax=txt.size.x;
         };
       };
      //write(largeurs[j]);
    };
    hauteurtotale+=hauteurs[i]+2margevertic;
  };
  //write(largeurmax);
  real larg=largeurmax;
  real h=0;
  pair[][] listepos;
  // on affiche
  for(int i=0; i< T.length; ++i) {
     h-=hauteurs[i]/2+margevertic;
     string[] TT=T[i];
     listepos[i]=new pair[];
     real l=0;
     for(int j=0; j< TT.length; ++j) {
       //write("i="+(string)i+" j="+(string)j+" larg="+(string)larg);
          //write("larg="+(string)largeurs[j]);
       larg=largeurs[j];
       if (j+1<TT.length) {
         l+=larg/2+margehoriz;
       } else {
         l+=margehoriz+textes[i][j].size.x/2;
       };
       listepos[i][j]=(l,h);
       //write("(l,h)="+(string)listepos[i][j]);
       //if (aff[i][j]==1) {
       add(textes[i][j],(l,h)); //};
       l+=larg/2+margehoriz;
       larg=largeurmax;
     };
       h-=hauteurs[i]/2+margevertic;
  };
  for(int i=0;i<listepos.length-1;++i) {
    pair p1=listepos[i][4]+(0,textes[i][4].min.y);
    pair p2=listepos[i][6]+(0,textes[i][4].min.y);
    pair p3=listepos[i+1][0]+(0,textes[i+1][0].max.y);
    pair p4=listepos[i+1][4]+(0,textes[i+1][4].max.y);
    path fleche1=p1{SW}..{SW}p3;
    path fleche2=p2{SW}..{SW}p4;

    //path fleche=pt1{d1}..{d2}pt2;
    if (afffleches || (aff[i+1][0]==1)) { draw(fleche1,ArcArrow(TeXHead));};
    if (afffleches || (aff[i+1][4]==1)) { draw(fleche2,ArcArrow(TeXHead));};

    //draw(F.texte,ellipse,midpoint(fleche)+F.offsett,FillDraw(fillpen=white));
  };
};


Et voici des exemples :
Code: Tout sélectionner
import geometry;
import tableau_proport;
unitsize(1cm); //important, sinon cela ne marche pas

tableau tutu={{"Dose d'huile","$2$","\ldots"},{"Dose de super","$3$","\ldots"}};
Fleche F1=Fleche("$\times k$",(2,0),(2,1),E,offseto=(0,-0.1),offsetd=(0,0.1),offsett=(0.2,0));
Fleche F2=Fleche("$: k$",(2,1),(2,0),3E,offseto=(0,-0.2),offsetd=(0,+0.2));
affichetableau(tutu,new Fleche[] {F2,F1},true,largmin=1,hautmin=0.8);

cours-tableau-prop-huile1.png
cours-tableau-prop-huile1.png (9.48 Kio) Vu 1224 fois


Code: Tout sélectionner
import geometry;
import tableau_proport;
unitsize(1cm);

tableau tab = {{"Nombre de crayons","$7$","$3$"},{"Prix en euros","$3,85$","$x$"}};
//Fleche F1=Fleche("$\times2$",(4,0),(4,1),E);
Fleche F2=Fleche("",(1,0),(2,1),(1,-0.2),(-1,0.2),Arrows(TeXHead,2bp),penfleche=heavygreen);
Fleche F3=Fleche("",(1,1),(2,0),(1,0.2),(-1,-0.2),Arrows(TeXHead,2bp),penfleche=heavyred);

affichetableau(tab,new Fleche[] {},new Fleche[] {F2,F3},true,largmin=1.5);

cours-produit-croix.png
cours-produit-croix.png (9.22 Kio) Vu 1224 fois


Code: Tout sélectionner
import geometry;
import tableau_proport;
unitsize(1cm);

affichepgcd(782,136);

cours-pgcd.png


Si vous avez des remarques ou commentaires...
Romain Janvier
Kilo-utilisateur
 
Messages: 146
Inscription: Lundi 23 Août 2010, 13:57
Statut actuel: Actif et salarié | Enseignant

Publicité

Re: Tableau de proportionnalité et PGCD

Messagepar GMaths » Mardi 11 Janvier 2011, 17:36

Romain Janvier a écrit:Si vous avez des remarques ou commentaires...

Une lecture très superficielle depuis le lycée... où je ne peux pas tester.

Ce genre de syntaxe (dont je n'avais plus le souvenir : j'ai dû rechercher unravel dans la doc) :

Code: Tout sélectionner
struct Person {
  string firstname;
  string lastname;

  static Person Person(string firstname, string lastname) {
    Person p=new Person;
    p.firstname=firstname;
    p.lastname=lastname;
    return p;
  }
}
from Person unravel Person;


ne peut-elle pas être remplacée par celle-ci plus claire, il me semble :

Code: Tout sélectionner
struct Person {
  string firstname;
  string lastname;

  void operator init(string firstname, string lastname) {
    this.firstname=firstname;
    this.lastname=lastname;
  }
}
GMaths
Exa-utilisateur
 
Messages: 2031
Inscription: Lundi 01 Octobre 2007, 09:20
Statut actuel: Actif et salarié | Enseignant

Re: Tableau de proportionnalité et PGCD

Messagepar Romain Janvier » Mardi 11 Janvier 2011, 18:24

On peut surement optimiser. Il me semble que j'ai pris modèle sur un exemple trouvé sur le net, mais je ne sais plus lequel. En regardant la doc, j'ai du prendre l'exemple qui se trouve juste en dessous de celui que tu as donné. Et ce n'etait pas le bon...
Romain Janvier
Kilo-utilisateur
 
Messages: 146
Inscription: Lundi 23 Août 2010, 13:57
Statut actuel: Actif et salarié | Enseignant

Re: Tableau de proportionnalité et PGCD

Messagepar GMaths » Mardi 11 Janvier 2011, 18:45

Romain Janvier a écrit:En regardant la doc, j'ai du prendre l'exemple qui se trouve juste en dessous de celui que tu as donné.

Au dessus, tu veux dire.
Et il me semble qu'ensuite, il propose la syntaxe avec "void operator init" comme simplification.
GMaths
Exa-utilisateur
 
Messages: 2031
Inscription: Lundi 01 Octobre 2007, 09:20
Statut actuel: Actif et salarié | Enseignant

Re: Tableau de proportionnalité et PGCD

Messagepar Romain Janvier » Mardi 11 Janvier 2011, 21:33

Oui tu as raison.

Sinon ave mes tableaux, on peut aussi mettre les fleches en haut ou en bas, pas juste sur les cotes. Par contre j'ai voulu faire une figure avec des fleches qui partent d'autres fleches, mais là j'ai du bidouiller. Il faudrait stocker les positions des textes sur les fleches, mais là, ca commence à faire vraiment compliqué pour simplement un ou deux cas où c'est utile.

Par contre il faudrait faire une fonction qui remplie le tableau automatiquement. Sauf que comme je l'utilise souvent en mettant des trous pour que les élèves les complètent, cela me generait plus qu'autre chose.
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 11 invités