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));
};
};
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);
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);
Code : Tout sélectionner
import geometry;
import tableau_proport;
unitsize(1cm);
affichepgcd(782,136);