Vos recrutements informatiques

700 000 développeurs, chefs de projets, ingénieurs, informaticiens...

Contactez notre équipe spécialiste en recrutement

Asymptote : Démarrage « rapide »

Cette documentation, très incomplète, est avant tout destinée à ceux qui voudraient débuter avec Asymptote. Si vous utilisez déjà ce logiciel depuis quelque temps, vous ne devriez pas apprendre grand chose... Mieux vaut vous concentrer sur la documentation officielle et les galeries d'exemples que l'on peut trouver sur internet (voir le paragraphe suivant).

Article lu   fois.

L'auteur

Profil Pro

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Installation

Tout d'abord, une distribution kitxmlcodeinlinelatexdvp\mathrm{\LaTeX}finkitxmlcodeinlinelatexdvp minimale doit être installée. Asymptote fait partie des principales distributions kitxmlcodeinlinelatexdvp\mathrm{\LaTeX}finkitxmlcodeinlinelatexdvp .

Pour savoir si Asymptote est installé, taper asy dans un terminal, vous verrez apparaître le numéro de version si c'est le cas. Taper quit pour sortir du mode interactif.

Sinon, il faut l'installer.

Ensuite, je ne traiterai pas l'installation sur Microsoft Windows ou MacOS X, ne connaissant pas (ou plus) ces systèmes. Vous trouverez tous les renseignements dans la documentation officielle, ou sur asymptote.sourceforge.net.

Sur Unix, il existe un paquet Asymptote sur la plupart des distributions, à installer par votre gestionnaire de paquet. Cependant, Asymptote étant un logiciel jeune, les mises à jour sont fréquentes. Pour avoir une version récente du logiciel, une compilation des sources pour installer la version svn est nécessaire.

Voici comment faire sur (X)Ubuntu 14.04.

Si Asymptote a été installé en même temps que TeX Live, par le script install-tl par exemple, il faut le supprimer à l'aide de tlmgr :

 
Sélectionnez
sudo tlmgr remove --force asymptote

Attention, il faut désinstaller toute version préalablement installée.

  1. Les paquets nécessaires

     
    Sélectionnez
    sudo apt-get install build-essential subversion flex texinfo autoconf zlib1g-dev
    sudo apt-get install bison libglut3 libglut3-dev cdbs debhelper libfftw3-dev
    sudo apt-get install libreadline6-dev libncurses5-dev libgsl0-dev libsigsegv-dev
  2. Récupérer les sources

     
    Sélectionnez
    mkdir asymptote_svn
    cd asymptote_svn
    svn co http://asymptote.svn.sourceforge.net/svnroot/asymptote/trunk/asymptote
  3. Compiler

     
    Sélectionnez
    cd asymptote
    ./autogen.sh
    wget http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc-7.1.tar.gz
    ./configure
    make all
    sudo make install
  4. Pour les mises à jour, c'est
 
Sélectionnez
cd asymptote_svn/asymptote
svn update
sudo make install

Remarques :

Si vous êtes sous Gnome, vous avez l'éditeur de texte Gedit déjà installé. Vous trouverez tout ce qu'il faut pour l'utiliser avec Asymptote à cette adresse : cgmaths.fr/Atelier/Asymptote/OutilsGedit.html

Un équivalent sur Windows est Notepad++, pour son utilisation, vous pouvez vous rendre dans la rubrique « Installation

d'Asymptote » sur le forum asy.gmaths.net/forum.

II. Les différentes compilations

II-A. Options de compilation

Les options de compilation sont très nombreuses (voir la documentation officielle). Nous ne nous intéresserons ici qu'à quelques-unes.

Créez un fichier texte,nommez le exemple.asy et collez-y un des codes d'exemple ci-après (pas le premier !). Enregistrez le document.

La compilation de ce code se fait en ligne de commande, avec les options par défaut, par

 
Sélectionnez
asy exemple.asy

Quelques options intéressantes :

-V : utile notamment pour les figures 3D, la figure s'ouvre dans une fenêtre de rendu OpenGL. La figure est alors manipulable, et un double clique-droit permet d'accéder à différents paramètres.

-noV : pour que le pdf (ou eps, ou autre) soit créé directement.

-f : pour préciser le format de sortie (pdf, . . .). Équivalent à settings.outformat="pdf"; (ou autre) dans le code de la figure.

-prc : pour les figures 3D: format prc d'adobe dans le pdf. Le pdf ne sera visualisable qu'avec une version suffisamment récente d'Acrobat Reader. La figure sera manipulable et on aura accès à un menu 3D.

-noprc : pas de format prc. La figure peut être visualisée dans n'importe quel lecteur pdf. Équivalent à settings.prc=false; dans le code de la figure.

-render n : rendu des figures 3D (n pixels/bp). Équivalent à settings.render=n; dans le code de la figure.

Exemple de compilation

 
Sélectionnez
asy -noV -noprc -f pdf exemple.asy

La figure produite peut être incluse dans un document .tex par un \includegraphics.

II-B. Compilation à l'intérieur d'un fichier .tex

Il sera vu le minimum ici. Pour davantage d'explications, voir la documentation officielle.

  • Méthode « classique »
    Il faut ajouter au début du document la ligne : \usepackage{asymptote}
    Le code de la figure doit être compris entre les balises \begin{asy} et \end{asy}.
 
Sélectionnez
\begin{asy}[width=\the\linewidth,inline=true]
…
\end{asy}
  • Ci-dessus sont précisées en options la largeur et inline=true qui permet d'utiliser des symboles LaTeX définis en dehors de l'environnement asy.
    La compilation se fait en trois temps :

    1. Une compilation latex (ou pdflatex). Un fichier .asy par figure est créé.
    2. Une compilation asy. Pour compiler toutes les figures, si le fichier tex s'appelle exemple.tex :

       
      Sélectionnez
      asy exemple-*.asy

      Les figures sont créées au format eps pour une compilation latex, ou au format pdf pour une compilation pdflatex.

    3. Une nouvelle compilation latex (ou pdflatex).
  • Latexmk
    Toutefois, il est dorénavant possible de tout compiler en une fois grâce à une version suffisamment récente du script latexmk. Ce script est peut-être déjà installé sur votre distribution ou alors il est téléchargeable sur le CTAN : www.ctan.org/tex-archive/support/latexmk/.
    Une fois installé, il faut créer un fichier nommé latexmkrc contenant :
 
Sélectionnez
sub asy {return system("asy '$_[0]'");}
add_cus_dep("asy","eps",0,"asy");
add_cus_dep("asy","pdf",0,"asy");
add_cus_dep("asy","tex",0,"asy");
  • Ce fichier peut être placé dans le même répertoire que le fichier tex.
    Note : sur linux, placer ce fichier une fois pour toutes dans le répertoire personnel en le nommant « .latexmkrc ».
    Attention, perl doit être installé sur l'ordinateur.
    Ensuite une seule compilation suffit :
 
Sélectionnez
latexmk -pdf exemple.tex
  • créera un pdf (seules les figures ayant été modifiées depuis la dernière compilation seront compilées).
    Remarque :
    Pour que les figures soient créées dans un sous-dossier figures, il faut rajouter dans le préambule du document tex :
 
Sélectionnez
\def\asydir{figures}
  • et remplacer la première ligne du fichier latexmkrc par :
    sub asy {return system("asy -o figures/ '$_[0]'");}
  • Package asypictureB
    Nouveau package, très bonne alternative à latexmk, mais ne fonctionne pas (encore) pour la 3D. Il suffit de l'importer dans le préambule à la place du package asymptote. Une seule compilation suffit : www.ctan.org/pkg/asypictureb.

III. Quelques généralités

Une bonne partie de la documentation officielle sera reprise ici. Les exemples de cette partie pourront être compilés simplement par : asy mafigure.asy (pour de l'eps) ou asy -f pdf mafigure.asy (pour du pdf).

III-A. Unités, dimensions de la figure

Contrairement à des logiciels comme GeoGebra, on ne peut pas placer de points « au hasard », tout se passe dans un repère : les points sont placés par leurs coordonnées. Ces coordonnées, appelées pairs sont en "big points" PostScript (1 bp = 1/72 inch).

Ainsi, avec le code 1, on ne verra rien ! la figure étant beaucoup trop petite...

Les codes 2 et 3 produiront la même figure, à savoir un segment de longueur kitxmlcodeinlinelatexdvp2\sqrt{2}\ \mathrm{cm}.finkitxmlcodeinlinelatexdvp

Code 1
Sélectionnez
pair A=(0,0), B=(2,2);
draw(A--B);
Code 2
Sélectionnez
pair A=(0,0), B=(2cm,2cm);
draw(A--B);
Code 3
Sélectionnez
unitsize(1cm);
pair A=(0,0), B=(2,2);
draw(A--B);

Remarques :

  • L'« unité » peut être différente pour les abscisses et les ordonnées : unitsize(1cm,1.5cm);
  • On peut aussi spécifier la taille finale de la figure produite :
    Pour une figure de 3cm de largeur, on précisera : size(3cm,0); (0 pour ne pas avoir à spécifier la hauteur, la mise à l'échelle étant automatique.)La taille peut être spécifiée en bp, pt, cm, mm ou inches.
  • -- est un connecteur qui joint les points par un segment. Les autres connecteurs sont .. , :: et --- (voir la documentation officielle).
Image non disponible
Image non disponible
Code 4
Sélectionnez
size(0,1cm);
draw((0,0)--(1,.5)--(2,0)--(3,.5),blue);
Code 5
Sélectionnez
size(0,1cm);
draw((0,0)..(1,.5)..(2,0)..(3,.5),blue);

III-B. Quelques commandes de dessins

  1. draw
 
Sélectionnez
void draw(picture pic=currentpicture, Label L="", path g,
          align align=NoAlign, pen p=currentpen,
          arrowbar arrow=None, arrowbar bar=None, margin margin=NoMargin,
          Label legend="", marker marker=nomarker)

Voyons en détail quelques options (pour les autres, voir la documentation officielle) :

  • picture pic=currentpicture : dessine dans l'image pic, par défaut currentpicture.
  • Label L="" : permet de placer un texte.
  • path g : le chemin à dessiner.
  • pen p=currentpen : le stylo à utiliser.
  • arrowbar arrow=None : Les flèches. Les valeurs possibles sont : None, Blank, BeginArrow, MidArrow, Arrow, et Arrows (flèches aux deux extrémités). On peut de plus préciser le type de tête (DefaultHead, SimpleHead, HookHead, TeXHead), la taille, l'angle de la tête, le type de remplissage (FillDraw, Fill, NoFill, UnFill, Draw) et la position relative.
    Il y a aussi certaines versions modifiées (taille et angle) : BeginArcArrow, MidArcArrow, ArcArrow, et ArcArrows.
  • arrowbar bar=None : Les barres aux extrémités. Les valeurs possibles sont : None, BeginBar, Bar et Bars. On peut préciser la taille.

    Image non disponible
    Code 6
    Sélectionnez
    size(5cm,0);
    path chemin=(0,0)..(1,.5)..(2,0)..(3,.5);
    draw("Chemin",chemin,blue,Arrow);
    draw(shift(0,-.6)*chemin,green,BeginArrow(5mm,Draw),Bar);
    draw(shift(0,-1.2)*chemin,.8*red,Arrows(TeXHead));
    draw(shift(0,-1.8)*chemin,bp+magenta,MidArrow(HookHead,Fill(blue)),Bars(2mm));
  • fill

     
    Sélectionnez
    void fill(picture pic=currentpicture, path g, pen p=currentpen)
    void filldraw(picture pic=currentpicture, path g,
                  pen fillpen=currentpen,pen drawpen=currentpen)

    Ces deux fonctions servent à remplir les chemins cycliques :

    Image non disponible
    Image non disponible
    Code 7
    Sélectionnez
    size(5cm,0);
    path rec=(0,0)--(1,0)--(1,.5)--(0,.5)--cycle;
    fill(rec,lightyellow);
    Code 8
    Sélectionnez
    size(5cm,0);path r=(0,0)--(1,0)--(1,.5)--(0,.5)--cycle;
    filldraw(r,fillpen=lightyellow,
         drawpen=2bp+.8green);
  • label
 
Sélectionnez
void label(picture pic=currentpicture, Label L, pair position,
           align align=NoAlign, pen p=nullpen, filltype filltype=NoFill)

Cette fonction permet de placer un texte au point de coordonnées position. Le texte peut être une simple chaîne de caractères (respectant la syntaxe LaTeX) ou une structure plus complexe obtenue par une fonction du type (il y en a d'autres, voir la documentation officielle) :

 
Sélectionnez
Label Label(string s="", pair position, align align=NoAlign,
            pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill)

align peut prendre n'importe quel pair comme valeurs. Certaines sont prédéfinies : N, S, E, W, NE, NW, SE, SW, LeftSide, RightSide, Center.

Voir les exemples qui suivent pour les différents paramètres.

Image non disponible
Image non disponible
Image non disponible
Code 9
Sélectionnez
size(5cm,0);
pair A=(0,0);
dot(A);
label("$N$",A,5*N);
label("$S$",A,5*S);
label("$E$",A,5*E);
label("$W$",A,5*W);
Code 10
Sélectionnez
size(5cm);
pair A=(0,0), B=(2,1);
path seg=A--B;
label("$A$",A,W);
label("$B$",B,E);
draw("$\sqrt{5}$",seg,
     linewidth(bp));
Code 11
Sélectionnez
size(5cm);
pair A=(0,0), B=(2,1);
path seg=A--B;
label("$A$",A,dir(A-B));
label("$B$",B,dir(B-A));
draw(Label("$\sqrt{5}$",
     align=LeftSide),
     seg,bp+deepgreen+dashed);
Image non disponible
Image non disponible
Image non disponible
Code 12
Sélectionnez
size(5cm);
pair A=(0,0), B=(2,1);
path seg=A--B;
label("$A$",A,dir(A-B));
label("$B$",B,dir(B-A));
draw(Label("$\sqrt{5}$",
           Rotate(dir(seg)),
           align=LeftSide),
    seg,blue);
Code 13
Sélectionnez
size(5cm);
pair A=(0,0), B=(2,1);
path seg=A--B;
label("$A$",A,dir(A-B));
label("$B$",B,dir(B-A));
draw(Label("$\sqrt{5}$",
           Rotate(dir(seg)),
           align=S),
     seg,longdashdotted);
Code 14
Sélectionnez
size(5cm);
pair A=(0,0), B=(2,1);
path seg=A--B;
label("$A$",A,dir(A-B));
label("$B$",B,dir(B-A));
draw(Label("$\sqrt{5}$",
           Rotate(dir(seg)),
           align=LeftSide,
           position=Relative(.75)),
     seg,bp+brown+dotted);
Image non disponible
Image non disponible
Image non disponible
Code 15
Sélectionnez
size(5cm);
pair A=(0,0), B=(1,0);
path seg=A--B;
label("$x'$",A,N);
label("$x$",B,N);
draw(Label("abscisses",
           filltype=Fill(orange)),
     seg,bp+deepcyan);
Code 16
Sélectionnez
unitsize(1cm);
pair A=(0,0), B=(4,0);
path seg=A--B;
label("$A$",A,W);
label("$B$",B,E);
draw(Label("$4$~cm",
           align=Center,
           filltype=UnFill),
           seg,bp+fuchsia,
           Arrows(SimpleHead),Bars);
Code 17
Sélectionnez
size(5cm,0);
import fontsize;
defaultpen(fontsize(10pt));
pair A=(0,0), B=(1,0);
draw(A--B,linewidth(bp));
label("$A$",A,W,.8blue);
pen f20=fontsize(20pt);
label("$B$",B,E,f20+brown);

Remarque :

Dans les exemples, B-A peut être interprété comme le vecteur AB.

On peut réaliser différentes opérations sur les pairs. Par exemple pair I=(A+B)/2; donnera le milieu I de [AB] (équivalent à pair I=midpoint(A—B);).

IV. Transformations

Présentation rapide des transformations d'Asymptote. Pour la première, pas besoin de figure. . . : transform identity();

Ensuite :

 
Sélectionnez
transform shift(pair z);
transform shift(real x,real y);
Image non disponible
Image non disponible
Code 18
Sélectionnez
size(7cm);
pair A=(0,0), B=(3,1);
path c=unitcircle;
path c1=shift(3,1)*c;
draw("$\mathcal{C}$",c);
draw("$\mathcal{C'}$",c1,bp+purple);
draw("$\overrightarrow{AB}$",
     A--B,blue,Arrow);
dot("$A$",A,SW);
dot("$B$",B,SE);
Code 19
Sélectionnez
size(4cm);
pair A=(0,0);
path c=unitcircle;
path c1=xscale(.5)*c;
path c2=yscale(.5)*c;
draw("$\mathcal{C}$",c);
draw("$\mathcal{C'}$",c1,E,bp+purple);
draw("$\mathcal{C''}$",c2,E,bp+royalblue);
dot("$A$",A,SW);
 
Sélectionnez
transform xscale(real x);
 
Sélectionnez
transform yscale(real y);
Image non disponible
Image non disponible
Code 20
Sélectionnez
size(4cm);
pair A=(0,0);
path c=unitcircle;
path c1=scale(.5)*c;
draw(scale(2)*"$\mathcal{C}$",c);
draw("$\mathcal{C'}$",c1,bp+purple);
dot("$A$",A,SW);
Code 21
Sélectionnez
size(7cm);
pair A=(0,0);
path c=unitcircle;
path c1=scale(2,.5)*c;
draw("$\mathcal{C}$",c);
draw("$\mathcal{C'}$",c1,bp+purple);
dot("$A$",A,SW);
 
Sélectionnez
transform slant(real s);

envoie le pair (x,y) sur (x+s*y,y)

 
Sélectionnez
transform rotate(real angle,pair z=(0,0));
Image non disponible
Image non disponible
Code 22
Sélectionnez
size(7cm);
pair A=(0,0);
path c=unitcircle;
path c1=slant(1.5)*c;
draw("$\mathcal{C}$",c,NW);
draw("$\mathcal{C'}$",c1,SE,bp+purple);
dot("$A$",A,SW);
Code 23
Sélectionnez
import markers; // pour utiliser markangle
size(7cm);
pair A=(0,0), B=(-1.5,-1);
transform rot=rotate(108,B);
path c=unitcircle;
pair A1=rot*A;
path c1=rot*c;
draw("$\mathcal{C}$",c,NW);
draw("$\mathcal{C'}$",c1,S,bp+purple);
draw(A--B--A1,dashed);
markangle("$\frac{3\pi}{5}$",A,B,A1,
          radius=6mm,Arrow);
dot("$A$",A,SE);dot("$A'$",A1,SW);
dot("$B$",B,SE);
 
Sélectionnez
transform reflect(pair a, pair b);
Image non disponible
Code 24
Sélectionnez
size(6cm);

pair A=(0,0), B=(.7,-1.3), C=(.7,1.3);

path c=unitcircle;
path c1=reflect(B,C)*c;
pair A1=reflect(B,C)*A;

draw("$\mathcal{C}$",c,NW);
draw("$\mathcal{C'}$",c1,NE,bp+purple);
draw(Label("$\mathcal{D}$",EndPoint),B--C,SW,.8red);
dot("$A$",A,SW);dot("$A'$",A1,SE,purple);

V. Quelques figures basiques

Voici quelques figures permettant de parcourir une partie des outils de base d'Asymptote.

Image non disponible
Image non disponible
Code 25
Sélectionnez
size(5cm,0);

pair A=(0,0);
path c=circle(A,1.5);
pair B=relpoint(c,0), C=relpoint(c,.15),
     D=relpoint(c,.65);
path a=subpath(c,reltime(c,.15),reltime(c,.65));
path b=subpath(c,3,4);

draw(c);
draw(a,bp+red);
draw(b,bp+green);
dot(c,linewidth(bp),UnFill);
dot("$A$",A,SW);dot("$B$",B,E,blue);
dot("$C$",C,NE,blue);dot("$D$",D,SW,blue);
Code 26
Sélectionnez
size(7cm,0);

pair A=(0,0), B=(-1.5,1), C=(1.5,1.5),
     D=(2.5,.5), pE=(2.5,-.5);
path seg1=A--C, seg2=B--D;
pair inter=intersectionpoint(seg1,seg2);
pair ext=extension(B,C,D,pE);
dot("intersectionpoint",inter,1.5*S,5bp+red);
dot("extension",ext,SE,5bp+blue);

draw(seg1,linewidth(bp));
draw(seg2,linewidth(bp));
draw(B--interp(B,C,2),dashed);
draw(pE--interp(pE,D,2.5),dashed);
dot("$A$",A,SW);dot("$B$",B,NW);
dot("$C$",C,N);dot("$D$",D,NE);
dot("$E$",pE,E);
Image non disponible
Code 27
Sélectionnez
size(7cm,0);

pair A=(0,0), B=(-2.5,-1), C=(3,.5);
path c=circle(A,1.5);
path d=interp(B,C,-.2)--interp(B,C,1.2);

draw(c,bp+heavyred);draw(d,bp+heavymagenta);
// tableau de pairs
pair[] inter=intersectionpoints(c,d);
for(int i=0; i<inter.length; ++i) {
    dot("inter"+string(i),inter[i],S,5bp+blue);
}
dot("$A$",A,NW);dot("$B$",B,NW);dot("$C$",C,N);
Image non disponible
Code 28
Sélectionnez
import patterns; // hachures
size(6cm,0);

pair A=(0,0), B=(3,0), C=(1,2);
path tri=A--B--C--cycle;
path c=circle(B,1.5);
pair[] P=intersectionpoints(tri,c);
path intersec=B--P[0]--arc(B,P[0],P[1],CW)--cycle;
// CW : ClockWise, CCW : Counter-ClockWise (défaut)
draw(tri);
draw(c);
// Définition des hachures :
add("hachure",hatch(3mm,NE,1.5mm+royalblue));
filldraw(intersec,pattern("hachure"));
dot("$P[0]$",P[0],SW);dot("$P[1]$",P[1],N);
dot("$A$",A,dir(C--A,B--A)); //direction de la bissectrice
dot("$B$",B,dir(C--B,A--B));dot("$C$",C,N);
Image non disponible
Code 29
Sélectionnez
size(6cm);
pair A=(0,0), B=(1,0), C=(1,.5), D=(1,-.5),
     pE=(3,.5), F=(3,-.5), G=(3,0), H=(4,0);
draw(A--B--C--pE--G--H);
draw(A—B--D--F--G--H);

draw("$R_1$",box,(2,.5),xmargin=3mm,ymargin=0,UnFill);
draw("$R_1$",box,(2,.5),xmargin=3mm,ymargin=0);

draw("$R_2$",box,(2,-.5),xmargin=3mm,ymargin=0,UnFill);
draw("$R_2$",box,(2,-.5),xmargin=3mm,ymargin=0);
Image non disponible
Code 30
Sélectionnez
unitsize(1cm);

defaultpen(fontsize(10pt));
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 \geqslant -3$",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);
});
Image non disponible
Code 31
Sélectionnez
size(4cm);
transform r=reflect((0,0),(0,1));
// Fonction pour tracer les boules
void boule(Label L="", pair a, pen p=currentpen, pen fillpen=nullpen) {
           filldraw(shift(a)*unitcircle,fillpen,p);
           label(scale(1.5)*L,a);
}
// Urne
pair A=(3.1,0), B=(3.1,4), C=(2.1,5), D=(1.1,6), pE=(1.1,7), F=(2.1,8), G=(3.1,8);
pair H=r*A;
path demi=G--F{dir(180)}..{dir(270)}pE--D{dir(270)}..{dir(0)}C{dir(0)}..{dir(-90)}B--A;
path demi2=r*demi;
draw(demi^^demi2,linewidth(3bp));draw(A--H,linewidth(3bp));
// Boules
boule("$5$",(0,1.1),linewidth(bp),gray+opacity(.7));
boule("$1$",(-2,1.1),linewidth(bp));
boule("$4$",(2,1.1),linewidth(bp));
boule("$3$",(-1,2.85),linewidth(bp),gray+opacity(.7));
boule("$1$",(1,2.85),linewidth(bp));
Image non disponible
Code 32
Sélectionnez
import markers;
size(4cm);
real ang=50;
pair A=(0,0), B=(3,0);
transform r=rotate(ang,A);
pair C=r*B;
path seg1=A--B;
path seg2=r*seg1;
draw(seg1^^seg2,linewidth(bp));
// fonction format, voir ci-contre
markangle(format("$%f^\circ$",ang),
          B,A,C,radius=6mm);
label("$A$",A,SW);
label("$B$",B,SE);
label("$C$",C,NE);
Image non disponible
Code 33
Sélectionnez
import labelpath;
size(0,3.5cm);
path p=(0,0)..(2,-1)..(2.5,-.5)..(3,-.75);
labelpath("\Large Fin de la pr\'esentation des outils de base",p,purple);
draw(p,heavygreen);

VI. Quelques modules

Je ne présenterai ici que les modules que j'utilise et donc que je connais un peu...

Pour les autres (graph3, grid3, interpolate, etc.), voir la documentation officielle, et les galeries d'exemples (asymptote.sourceforge.net).

VI-A. markers

Le module markers fournit tout ce qu'il faut pour marquer segments et angles.

Les marqueurs pour les segments sont :

 
Sélectionnez
marker StickIntervalMarker(int i=2, int n=1, real size=0, real space=0,
                           real angle=0, pair offset=0, bool rotated=true,
                           pen p=currentpen, frame uniform=newframe,
                           bool above=true)
Image non disponible
Image non disponible
Code 34
Sélectionnez
import markers;
size(7cm,0);
pair A=(0,0), B=(3,0);
draw(A—B,StickIntervalMarker(3,2,
     angle=25,dotframe(purple)));
label("$A$",A,W);label("$B$",B,E);
Code 35
Sélectionnez
import markers;
size(7cm,0);
pair A=(0,0), B=(3,0);
draw(A--B,StickIntervalMarker(4,1,size=5mm,
     angle=-45,bp+.8green,dotframe(purple)));
label("$A$",A,W);label("$B$",B,E);
 
Sélectionnez
marker CrossIntervalMarker(int i=2, int n=3, real size=0, real space=0,
                           real angle=0, pair offset=0, bool rotated=true,
                           pen p=currentpen, frame uniform=newframe,
                           bool above=true)
Image non disponible
Image non disponible
Code 36
Sélectionnez
import markers;
size(7cm,0);
pair A=(0,0), B=(3,0);
draw(A--B,CrossIntervalMarker(2,4,angle=0,
     bp+red,dotframe(purple)));
label("$A$",A,W);label("$B$",B,E);
Code 37
Sélectionnez
import markers;
size(7cm,0);
pair A=(0,0), B=(3,0);
draw(A--B,CrossIntervalMarker(3,6,size=2mm,
     angle=45,bp+blue,dotframe(purple)));
label("$A$",A,W);label("$B$",B,E);
 
Sélectionnez
marker CircleBarIntervalMarker(int i=2, int n=1, real barsize=0, real radius=0,
                               real angle=0, pair offset=0, bool rotated=true,
                               pen p=currentpen, filltype filltype=NoFill,
                               bool circleabove=false, frame uniform=newframe,
                               bool above=true)
Image non disponible
Image non disponible
Code 38
Sélectionnez
import markers;
size(7cm,0);
pair A=(0,0), B=(3,0);
draw(A--B,CircleBarIntervalMarker(3,2,
     barsize=5mm,radius=1.5mm,
     angle=-45,darkgreen,
     filltype=NoFill,dotframe(purple)));
label("$A$",A,W);label("$B$",B,E);
Code 39
Sélectionnez
import markers;
size(7cm,0);
pair A=(0,0), B=(3,0);
draw(A--B,CircleBarIntervalMarker(4,1,
     barsize=5mm,radius=1.5mm,bp+blue,
     filltype=Fill(brown),
     circleabove=true,
     dotframe(purple),above=false));
label("$A$",A,W);label("$B$",B,E);
Image non disponible
Image non disponible
Code 40
Sélectionnez
import markers;
size(7cm,0);
pair A=(0,0), B=(3,0);
draw(A--B,CircleBarIntervalMarker(4,1,
     barsize=5mm,radius=1.5mm,
     bp+blue,filltype=Fill(brown),
     dotframe(purple)));
label("$A$",A,W);label("$B$",B,E);
Code 41
Sélectionnez
import markers;
size(7cm,0);
pair A=(0,0), B=(3,0);
draw(A--B,CircleBarIntervalMarker(3,0,
     radius=1.2mm,bp+fuchsia,
     filltype=NoFill,dotframe(purple)));
label("$A$",A,W);label("$B$",B,E);
 
Sélectionnez
marker TildeIntervalMarker(int i=2, int n=1, real size=0, real space=0,
                           real angle=0, pair offset=0, bool rotated=true,
                           pen p=currentpen, frame uniform=newframe,
                           bool above=true)
Image non disponible
Image non disponible
Code 42
Sélectionnez
import markers;
size(7cm,0);
pair A=(0,0), B=(3,0);
draw(A--B,TildeIntervalMarker(3,2,size=1mm,
     space=4mm,bp+orange,
     dotframe(purple),above=false));
label("$A$",A,W);label("$B$",B,E);
Code 43
Sélectionnez
import markers;
size(7cm,0);
pair A=(0,0), B=(3,0);
draw(A--B,TildeIntervalMarker(4,1,size=1mm,
     angle=-40,offset=(0,2),bp+darkcyan,
     dotframe(purple),above=true));
label("$A$",A,W);label("$B$",B,E);

Il est bien sûr possible de définir ses propres « markers » :

Image non disponible
Code 44
Sélectionnez
import markers;
size(7cm,0);
pair A=(0,0), B=(3,0);
frame cg;
filldraw(cg,scale(5)*polygon(7),Yellow,bp+Magenta);
marker markcg = marker(crossframe(n=4,size=1.5mm,bp+purple),
                       markinterval(2,cg,true));
draw(A--B,markcg);
label("$A$",A,W);label("$B$",B,E);

Les marques prédéfinies sont :

 
Sélectionnez
frame stickframe(int n=1, real size=0, pair space=0, real angle=0,
                 pair offset=0, pen p=currentpen)

frame circlebarframe(int n=1, real barsize=0,
                     real radius=0,real angle=0,
                     pair offset=0, pen p=currentpen,
                     filltype filltype=NoFill, bool above=false)
                     frame crossframe(int n=3, real size=0, pair space=0,
                     real angle=0, pair offset=0, pen p=currentpen)

frame tildeframe(int n=1, real size=0, pair space=0,
                 real angle=0, pair offset=0, pen p=currentpen)

Pour marquer l'angle AOB (dans le sens direct), on dispose de :

 
Sélectionnez
void markangle(picture pic=currentpicture, Label L="",
               int n=1, real radius=0, real space=0,
               pair A, pair O, pair B, arrowbar arrow=None,
               pen p=currentpen, filltype filltype=NoFill,
               margin margin=NoMargin, marker marker=nomarker)
Image non disponible
Image non disponible
Code 45
Sélectionnez
import markers;
size(5cm,0);
pair O=(0,0), A=(2,0), B=(1,1.5);
draw(A--O--B);
markangle(scale(1.5)*"$\alpha$",radius=40,
          A,O,B,ArcArrow,bp+red);
markangle(scale(1.5)*"$\beta$",radius=30,
          B,O,A,BeginArcArrow(HookHead,2mm),
          bp+deepgreen);
label("$O$",O,SW);
label("$A$",A,SE);label("$B$",B,N);
Code 46
Sélectionnez
import markers;
size(5cm,0);
pair O=(0,0), A=(2,0), B=(1,1.5),
     C=A+dir(A—O,A--B);

markangle(n=2,radius=20,
          A,O,B,p=2bp+deepcyan,
          filltype=Fill(magenta));
markangle(n=1,radius=20,
          O,B,A,p=2bp+deepcyan,
marker(markinterval(stickframe(n=2,
       4mm,bp+red),true)));
markangle(n=2,radius=20,
          B,A,O,p=bp+heavyblue,
marker(markinterval(2,stickframe(n=1,
       2mm,bp+purple),true)));

draw(A--interp(A,C,2),bp+dashed);
draw(A--O--B--cycle,linewidth(bp));
label("$O$",O,SW);
label("$A$",A,SE);label("$B$",B,N);

VI-B. geometry

Ce module apporte un grand nombre d'outils permettant de faciliter la construction de figures géométriques dans le plan.

Une fois n'est pas coutume, il y a une vraie documentation en français, faite par l'auteur du module : Philippe Ivaldi. On la trouve ici : www.piprime.fr/files/res/geometry_fr.pdf

Elle est extrêmement complète. Il existe de plus un index à cette adresse : www.piprime.fr/files/asymptote/geometry/modules/geometry.asy.index.type.html

Ce qui suit n'est ni plus ni moins qu'un copié-collé d'une toute petite partie de cette documentation dont la lecture est essentielle.

VI-B-1. De nouveaux types d'objets sont définis :

  • coordsys: permet d'utiliser n'importe quel repère cartésien.
  • point : équivalent au type pair dans le repère par défaut.
  • vector : aussi équivalent au type pair dans le repère par défaut.
  • mass : pour les barycentres.
  • line : quelques objets de type line :
  • line line(point A, bool extendA=true, point B, bool extendB=true)
    Pour les droites, demi-droites (extendA=false ou extendB=false) et segments de droites (extendA=false et extendB=false).
    line line(coordsys R=currentcoordsys, real a, real b, real c)
    Renvoie la droite d'équation kitxmlcodeinlinelatexdvpax+by +c = 0finkitxmlcodeinlinelatexdvp dans le repère R.
    line line(coordsys R=currentcoordsys, real slope, real origin)
    Renvoie la droite de pente slope et d'ordonnée à l'origine origin donnés relativement au repère R.
    line parallel(point M, line l)
    Renvoie la droite parallèle à l passant par M.
    line parallel(point M, explicit vector dir)
    Renvoie la droite de vecteur directeur dir et passant par M.
    line parallel(point M, explicit pair dir)
    Renvoie la droite de vecteur directeur dir donné dans le repère courant currentcoordsys et passant par M.
    line line(real a, point A=point(currentcoordsys,(0,0)))
    Renvoie la droite passant par A et faisant un angle de a degrés avec l'axe des abscisses du repère dans lequel est défini A.
    line bisector(line l1, line l2, real angle=0, bool sharp=true)
    Renvoie l'image de la bissectrice de l'angle formé par les droites orientées l1 et l2 par la rotation de centre « l'intersection de l1 et l2 » et d'angle angle. Si le paramètre sharp vaut true, renvoie la bissectrice de l'angle aigu.
    line sector(int n=2, int p=1, line l1, line l2, real angle=0, bool sharp=true)
    Renvoie l'image de la p-ième droite qui partage l'angle formé par les droites orientées l1 et l2 en n parties égales par la rotation de centre « l'intersection de l1 et l2 » et d'angle angle. Si le paramètre sharp vaut true, considère l'angle aigu.
    line perpendicular(point M, line l)
    Renvoie la droite perpendiculaire à l passant par M.
    line perpendicular(point M, explicit vector normal)
    Renvoie la droite passant par M et de vecteur normal normal.
    line perpendicular(point M, explicit pair normal)
    Renvoie la droite passant par M et de vecteur normal normal donné dans le repère courant currentcoordsys.
    line reverse(line l)
    Renvoie la droite représentée par l avec une orientation contraire à celle de l.
    line extend(line l)
    Renvoie la droite portée par l qui peut être une demi-droite ou un segment de droite.
    line complementary(explicit line l)
    Renvoie la demi-droite complémentaire de l. Ne fonctionne que si l représente effectivement une demi-droite.
  • Segment :
    segment segment(point A, point B)
    On notera notamment la routine :
    line bisector(segment s, real angle=0)
    qui renvoie l'image de la médiatrice de s par la rotation de centre « le milieu de s » et d'angle angle.
    Ainsi que :
    line[] complementary(explicit segment s)
    qui renvoie sous forme de tableau les deux demi-droites de support s et d'extrémités respectives s.A et s.B.
  • conic : pour une conique quelconque non dégénérée. Les types dérivés sont : circle, ellipse, parabola et hyperbola.
    De nombreuses routines permettent de définir un cercle. Entre autres :
    circle circle(explicit point C, real r)
    Renvoie le cercle de centre C et de rayon r.
    circle circle(point A, point B)
    Renvoie le cercle de diamètre AB.
    circle circle(point A, point B, point C)
    Renvoie le cercle passant par les points distincts A, B et C.
    Etc. (Voir la documentation)
  • arc : pour les arcs orientés d'ellipses.
    arc arc(ellipse el, real angle1, real angle2,polarconicroutine polarconicroutine=polarconicroutine(el), bool direction=CCW)
  • abscissa : pour instancier une abscisse sur un objet de type line, segment, conic et arc.
  • triangle : structure assez complexe bénéficiant de nombreuses routines. Encore une fois, le minimum sera vu. Ici, la lecture de la documentation est essentielle.

     
    Sélectionnez
    struct triangle {
        restricted point A, B, C; // points marquant les sommets du triangle
    struct vertex { // sommet de triangle
        int n;
        triangle t; }
    restricted vertex VA, VB, VC; // les sommets du triangle
    struct side { // côté de triangle
        int n;
        triangle t; }
    side AB, BC, CA, BA, AC, CB; } // les côtés du triangle
     
    Sélectionnez
    void label(picture pic=currentpicture, Label LA="$A$",
               Label LB="$B$", Label LC="$C$",
               triangle t,
               real alignAngle=0,
               real alignFactor=1,
               pen p=nullpen, filltype filltype=NoFill)

  • Place les labels LA, LB et LC aux sommets du triangle t, alignés suivant la première bissectrice du sommet correspondant.
    Les paramètres alignAngle et alignFactor permettent de modifier la direction et la longueur de l'alignement.

     
    Sélectionnez
    void show(picture pic=currentpicture,
              Label LA="$A$", Label LB="$B$", Label LC="$C$",
              Label La="$a$", Label Lb="$b$", Label Lc="$c$",
              triangle t, pen p=currentpen, filltype filltype=NoFill)

  • Trace le triangle t et affiche les labels aux sommets du triangle ainsi que les longueurs de ses côtés. Cette routine est surtout utile pour localiser les sommets t.A, t.B et t.C en cours de codage.

     
    Sélectionnez
    void draw(picture pic=currentpicture, triangle t,
              pen p=currentpen, marker marker=nomarker)
  • Trace le triangle t ; les côtés sont tracés comme des segments.
    void drawline(picture pic=currentpicture, triangle t, pen p=currentpen)
    Trace le triangle t ; les côtés sont tracés comme des droites.
    triangle triangle(point A, point B, point C)
    Renvoie le triangle dont les sommets sont A, B et C.
    triangle triangleabc(real a, real b, real c, real angle=0, point A=(0,0))
    Retourne le triangle ABC tel que BC=a, AC=b, AB=c et
    triangle triangleAbc(real alpha, real b, real c, real angle=0, point A=(0,0))
    Retourne le triangle ABC tel que

    kitxmlcodelatexdvp\left(\vec{AB};\vec{AC}\right)= \mathrm{alpha}finkitxmlcodelatexdvp

    , AC=b, AB=c et

    kitxmlcodelatexdvp\left(\vec{\imath};\vec{AB}\right)= \mathrm{angle}.finkitxmlcodelatexdvp


    triangle triangle(line l1, line l2, line l3)
    Renvoie le triangle dont les côtés sont l1, l2 et l3.
    Et de nombreuses autres routines permettant de tracer l'orthocentre, les hauteurs, le centre de gravité, les médianes, etc.

  • trilinear : instancie des coordonnées trilinéaires relatives à un triangle (sic).

  • inversion : permet d'instancier l'inversion de pôle C et de puissance k.
 
Sélectionnez
struct inversion
{
point C;
real k;
}

VI-B-2. De nouvelles transformations sont définies :

transform scale(real k, point M)

Homothétie de centre M et de rapport k.

transform scale(real k, line l1, line l2, bool safe=false)

Renvoie l'affinité de rapport k, d'axe l1 et de direction l2.

Si safe vaut true et l1 parallèle à l2, la routine renvoie l'identité.

transform projection(point A, point B)

Projection orthogonale sur la droite (AB).

transform projection(line l)

Renvoie la projection orthogonale sur l.

transform projection(point A, point B, point C, point D, bool safe=false)

Projection sur la droite (AB) parallèlement à (CD).

Si safe vaut true et (AB) est parallèle à (CD), l'identité est renvoyée.

Si safe vaut false et (AB) est parallèle à (CD), l'homothétie de centre O et de rapport infini est renvoyée.

transform projection(line l1, line l2, bool safe=false)

Renvoie la projection sur l1 parallèlement à l2.

Si safe vaut true et l1 parallèle à l2, la routine renvoie l'identité.

transform vprojection(line l, bool safe=false)

Renvoie la projection sur l parallèlement à la verticale.

Si safe vaut true et l est une droite verticale, la routine renvoie l'identité.

transform hprojection(line l, bool safe=false)

Renvoie la projection sur l parallèlement à l'horizontale.

Si safe vaut true et l est une droite horizontale, la routine renvoie l'identité.

transform scale(real k, point A, point B, point C, point D, bool safe=false)

Affinité de rapport k, d'axe (AB) et de direction (CD). Si safe vaut true et (AB) est parallèle à (CD), l'identité est renvoyée.

Si safe vaut false et (AB) est parallèle à (CD), l'homothétie de centre O et de rapport infini est renvoyée.

transform xscale(real k, point M)

Affinité de rapport k, d'axe « l'axe passant par M et parallèle à (Oy) » et de direction (Ox).

transform yscale(real k, point M)

Affinité de rapport k, d'axe « l'axe passant par M et parallèle à (Ox) » et de direction (Oy).

transform scaleO(real x)

Homothétie de rapport x et de centre « l'origine du repère courant ». Cette transformation est identique à scale(x, origin()).

transform xscaleO(real x)

Identique à xscale(x, origin()).

transform yscaleO(real x)

Identique à yscale(x, origin()).

transform rotateO(real angle)

Identique à rotate(angle, origin()).

transform reflect(line l)

Renvoie la réflexion par rapport à l.

VI-B-3. geometry introduit aussi des fonctions de marquage :

 
Sélectionnez
void distance(picture pic=currentpicture, Label L="", point A, point B,
              bool rotated=true, real offset=3mm,
              pen p=currentpen, pen joinpen=invisible,
              arrowbar arrow=Arrows(NoFill))
              
void markrightangle(picture pic=currentpicture, point A, point O,
                    point B, real size=0, pen p=currentpen,
                    margin margin=NoMargin,
                    filltype filltype=NoFill)
                    
void perpendicularmark(picture pic=currentpicture, point z,
                       explicit pair align,
                       explicit pair dir=E, real size=0,
                       pen p=currentpen,
                       margin margin=NoMargin,
                       filltype filltype=NoFill)
                       
void perpendicularmark(picture pic=currentpicture, point z,
                       vector align,
                       vector dir=E, real size=0,
                       pen p=currentpen,
                       margin margin=NoMargin,
                       filltype filltype=NoFill)
                       
void perpendicularmark(picture pic=currentpicture, point z, explicit pair align, path g,
                       real size=0, pen p=currentpen,
                       margin margin=NoMargin,
                       filltype filltype=NoFill)
                       
void perpendicularmark(picture pic=currentpicture, point z, vector align, path g,
                       real size=0, pen p=currentpen,
                       margin margin=NoMargin,
                       filltype filltype=NoFill)
                       
path compassmark(pair O, pair A, real position, real angle=10)

À noter aussi la routine :

 
Sélectionnez
void addMargins(picture pic=currentpicture,
                real lmargin=0, real bmargin=0,
                real rmargin=lmargin, real tmargin=bmargin,
                bool rigid=true, bool allObject=true)

Pour le tracé des droites, ajoute des marges à l'image (remplace avantageusement interp).

Si rigid vaut false, les marges sont ajoutées si et seulement si une courbe infinie se prolonge jusqu'à la marge.

Si allObject vaut false, les objets de taille fixe (comme les labels et pointes de flèches) seront ignorés.

Quelques exemples :

Image non disponible
Image non disponible
Code 47
Sélectionnez
import geometry;
size(7cm);

real ac=3, am=2, coef=am/ac;
triangle t=triangleAbc(40,ac,4);
drawline(t); label("$A$",t.A,NW);
label("$B$",t.B,NE); label("$C$",t.C,2N);
point M=relpoint(line(t.AC),-coef);
line par=parallel(M,t.BC);
draw(par);
point pN=intersectionpoint(par,t.AB);
label("$M$",M,2*S);
label("$N$",pN,N+.5*E);

addMargins(1cm,.5cm);
Code 48
Sélectionnez
import geometry;
size(6cm);

triangle t=triangleabc(4,5,6);
label(t); draw(t,linewidth(bp));

point pE=midpoint(t.AB),
      pF=t.A+(1/3)*(t.C-t.A),
      pG=t.B+(1/3)*(t.C-t.B);
dot("$E$",pE,-dir(t.VC));
dot("$F$",pF,-dir(t.VB));
dot("$G$",pG,-dir(t.VA));

draw(segment(t.AB),
     StickIntervalMarker(2,2,angle=-35));
draw(t.C--pE^^t.B--pF^^t.A--pG);

line CE=line(t.C,pE);
line AG=line(t.A,pG);
dot(intersectionpoint(CE,AG));
Image non disponible
Image non disponible
Code 49
Sélectionnez
import geometry;
size(6cm);

triangle t=triangleabc(4,5,6);
label(t); draw(t,linewidth(bp));

point pE=midpoint(t.AB),
      pF=t.A+(1/3)*(t.C-t.A),
      pG=t.B+(1/3)*(t.C-t.B);
dot("$E$",pE,-dir(t.VC));
dot("$F$",pF,-dir(t.VB));
dot("$G$",pG,-dir(t.VA));

draw(segment(t.AB),
     StickIntervalMarker(2,2,angle=-35));
draw(t.C--pE^^t.B--pF^^t.A--pG);

line CE=line(t.C,pE);
line AG=line(t.A,pG);
dot(intersectionpoint(CE,AG));
Code 50
Sélectionnez
import geometry;
size(6cm);

triangle t=triangleabc(4,5,6);
label(t); draw(t,linewidth(bp));

point pE=midpoint(t.AB),
      pF=t.A+(1/3)*(t.C-t.A),
      pG=t.B+(1/3)*(t.C-t.B);
dot("$E$",pE,-dir(t.VC));
dot("$F$",pF,-dir(t.VB));
dot("$G$",pG,-dir(t.VA));

draw(segment(t.AB),
     StickIntervalMarker(2,2,angle=-35));
draw(t.C--pE^^t.B--pF^^t.A--pG);

line CE=line(t.C,pE);
line AG=line(t.A,pG);
dot(intersectionpoint(CE,AG));
Image non disponible
Image non disponible
Code 51
Sélectionnez
size(8cm);
import geometry;
usepackage("fourier");

void filldrawtri(triangle t,
                 pen fpen=currentpen, pen dpen=currentpen)
{
filldraw(t.A--t.B--t.C--cycle,fpen,dpen);
}
point A=(0,0),B=(3,0),C=(1,2.5),pI=(A.x,C.y);
point D=(4,0),pE=(7,0),G=(8.5,2.5),F=(G.x,0);
point H=projection(A,B)*C;
triangle t1=triangle(A,B,C);
triangle t2=triangle(D,pE,G);

filldrawtri(t1,lightgreen,linewidth(bp));
filldrawtri(t2,lightred,linewidth(bp));

draw(C--H^^pE--F^^G--F,dashed);
markrightangle(C,H,A,3mm);
markrightangle(G,F,D,3mm);
distance("$\frac{1}{3}$",A,H,4mm,
         Arrows(1mm,NoFill));
distance("$\frac{1}{2}$",H,B,4mm);
distance("$\frac{3}{5}$",A,pI,
         rotated=false,-2mm);
distance("$\frac{3}{4}$",D,pE,4mm);
distance("$\frac{2}{3}$",F,G,rotated=false);
Code 52
Sélectionnez
import geometry;
usepackage("fourier","upright");
usepackage("mathrsfs");
size(6cm);

triangle t=triangleAbc(75,7,8.5,225);
point H=foot(t.VA);
circle c=circle(t.A,H);
point[] ct=intersectionpoints(t,c);

draw(t,heavyblue);
draw(t.A--H);
draw(c,red);
draw(ct[0]--ct[3],deepgreen);

label(t,heavyblue);dot("$O$",c.C,W);
label("$\mathscr{C}$",angpoint(c,50),NE,red);
label("$H$",H,NW);
label("$D$",ct[0],NW,deepgreen);
label("$E$",ct[3],E,deepgreen);
markrightangle(t.A,H,t.C);
markangle(scale(.8)*"$45^\circ$",5mm,
          t.B,t.A,H);
markangle(scale(.8)*"$30^\circ$",n=2,6mm,
          H,t.A,t.C);
Image non disponible
 
Sélectionnez
import geometry;
usepackage("fourier","upright"); usepackage("mathrsfs");
size(10cm);
pen mediane=brown, bissec=heavymagenta, mediat=deepcyan, ortho=deepgreen;
// ----------------------------------------------------------------------
triangle t=triangleabc(5,4,6); drawline(t); label(t);
// ----------------------------------------------------------------------
line med=median(t.VA); point A1=midpoint(t.BC); point G=centroid(t);
draw(med,mediane); dot("$A'$",A1,N+.5*E,mediane); dot("$G$",G,S,mediane);
// ----------------------------------------------------------------------
line biss=bisector(t.VC); point Bi=bisectorpoint(t.AB);
point Ci=incenter(t); circle ci=incircle(t);
draw(biss,bissec); draw(ci,bissec);
dot("$C_1$",Bi,SE,bissec); dot("$I$",Ci,N+.5*E,bissec);
// ----------------------------------------------------------------------
line mediatrice=bisector(t.AC); point B1=midpoint(t.AC);
point Cc=circumcenter(t); circle cc=circle(t);
draw(mediatrice,mediat); draw(cc,mediat);
dot("$B'$",B1,N,mediat); dot("$O$",Cc,E+.5*N,mediat);
// ----------------------------------------------------------------------
line haut=altitude(t.VC); point C2=foot(t.VC);
point orth=orthocentercenter(t);
draw(haut,ortho); dot("$C_2$",C2,SW,ortho); dot("$H$",orth,SW,ortho);
// ----------------------------------------------------------------------
draw(line(orth,Cc),dashdotted);
label(Label("droite d'Euler",Rotate(dir(orth--Cc)),align=RightSide),
     relpoint(line(orth,Cc),1.7));
// ----------------------------------------------------------------------
addMargins(.5cm,.5cm);

VI-C. trembling

Ce module permet de faire des figures « à main levée ». Plusieurs paramètres permettent de modifier l'effet :

 
Sélectionnez
real magneticRadius=1;
real trembleFuzz(){return min(1e-3,magneticRadius/10);}
real trembleAngle=4, trembleFrequency=0.5, trembleRandom=2;

Pour saisir leur rôle, le plus simple est de faire des essais. Des explications sont données directement dans le fichier trembling.asy.

Il faut utiliser la structure tremble, ainsi que la méthode deform :

 
Sélectionnez
tremble tremble(real angle=trembleAngle, real frequency=trembleFrequency,
                real random=trembleRandom, real fuzz=trembleFuzz())

path deform(path g...pair[] magneticPoints)

Il faudra donc impérativement un type path ...

Image non disponible
Image non disponible
Code 54
Sélectionnez
import trembling;
import geometry;
size(5cm,0);
pair A=(0,0), B=(3,0), C=(0,2),
     O=midpoint(B--C);
path t=B--A--C--cycle;
// paramètres par défaut
tremble tr=tremble(angle=4,
                   frequency=.5,
                   random=2);
draw(tr.deform(t),blue);
path c=circle(O,sqrt(13)/2);
draw(c);
markrightangle(B,A,C,bp+darkmagenta,
               filltype=Fill(Yellow));
Code 55
Sélectionnez
import trembling;
import geometry;
size(5cm,0);
pair A=(0,0), B=(3,0), C=(0,2),
     O=midpoint(B--C);
path t=B--A--C--cycle;
tremble tr=tremble(angle=10,
                   frequency=.5, random=2);
draw(tr.deform(t),blue);
path c=circle(O,sqrt(13)/2);
draw(c);
markrightangle(B,A,C,bp+darkmagenta,
               filltype=Fill(Yellow));
Image non disponible
Image non disponible
Cod 56
Sélectionnez
import trembling;
import geometry;
tremble tr=tremble(angle=6,
                   frequency=1,
                   random=5);
size(5cm,0);
pair A=(0,0), B=(3,0), C=(0,2),
     O=midpoint(B--C);
path t=B--A--C--cycle;
path c=circle(O,sqrt(13)/2);
draw(tr.deform(t),blue);
dot(A^^B^^C);
draw(tr.deform(c));
markrightangle(B,A,C,bp+darkmagenta,
               filltype=Fill(Yellow));
Code 57
Sélectionnez
import trembling;
import geometry;
tremble tr=tremble(angle=6,
frequency=1,
random=5);
size(5cm,0);
pair A=(0,0), B=(3,0), C=(0,2),
     O=midpoint(B--C);
path t=B--A--C--cycle;
path c=circle(O,sqrt(13)/2);
draw(tr.deform(t),blue);
dot(A^^B^^C);
// A, B et C "magnétisés" :
draw(tr.deform(c,A,B,C));
markrightangle(B,A,C,bp+darkmagenta,
               filltype=Fill(Yellow));
label(scale(.7)*"magneticPoints",
      C,9E,.8red);

VI-D. graph

La documentation officielle est très complète sur ce module. Ce qui suit est un résumé de ce qui sera le plus utile dans un premier temps.

VI-D-1. Axes et repères

graph fournit les routines suivantes :

 
Sélectionnez
void xaxis(picture pic=currentpicture, Label L="", axis axis=YZero,
           real xmin=-infinity, real xmax=infinity, pen p=currentpen,
           ticks ticks=NoTicks, arrowbar arrow=None, bool above=false);

Dessine l'axe des abscisses. Certains paramètres méritent de s'y attarder :

  • axis : détermine la position de l'axe. Les différents types sont :

    • YZero(bool extend=true) : l'axe a pour équation y = 0 (ou y =.1 pour une échelle logarithmique).
      extend=true (valeur par défaut) pour que l'axe soit aux dimensions complètes de la figure.
    • YEquals(real Y, bool extend=true) : l'axe a pour équation y = Y. (Voir plutôt yequals.)
    • Bottom(bool extend=false) : l'axe est au bas de la figure.
    • Top(bool extend=false) : l'axe est en haut.
    • BottomTop(bool extend=false) : axes en bas et en haut.
  • xmin et xmax : automatiquement déterminés par les dimensions de la figure si non spécifiés.
  • ticks : les traits de graduation. Les valeurs sont NoTicks (par défaut, aucune graduation), LeftTicks (graduations uniquement à gauche de l'axe), RightTicks (graduations uniquement à droite de l'axe) et Ticks (graduations des deux cotés de l'axe). Ces trois dernières routines prennent elles-mêmes de nombreux arguments en option :

     
    Sélectionnez
    ticks Ticks(Label format="", ticklabel ticklabel=null,
                bool beginlabel=true, bool endlabel=true,
                int N=0, int n=0, real Step=0, real step=0,
                bool begin=true, bool end=true, tickmodifier modify=None,
                real Size=0, real size=0, bool extend=false,
                pen pTick=nullpen, pen ptick=nullpen);
  • format : format des nombres sur les axes (par défaut "$%.4g$"). Pour n'avoir que les traits, sans les labels, la valeur est "%".

  • ticklabel : fonction string(real x) qui retourne le label (par défaut format(format.s,x)) de chaque graduation principale d'abscisse x. Voir par exemple labelfrac page 41 et le code 73.
    Le ticklabel OmitFormat(string s=defaultformat ... real[] x) permet d'enlever certains labels, mais pas la graduation correspondante.
    NoZeroFormat est une abréviation pour OmitFormat(0).

  • beginlabel et endlabel : inclut le premier et le dernier label.

  • N : Quand la mise à l'échelle est activée (par défaut), l'axe est divisé en N intervalles séparés par les graduations principales.

  • n : Chaque intervalle principal est divisé en n intervalles secondaires séparés par les graduations secondaires.

  • Step : la valeur entre chaque trait de graduation principale (si N=0).

  • step : la valeur entre chaque trait de graduation secondaire (si n=0).

  • begin et end : inclut le premier et le dernier trait de graduation principale.

  • tickmodifier modify : fonction permettant de modifier des graduations « manuellement ».
    Certains tickmodifier sont prédéfinis :
    OmitTick(... real[] x), OmitTickInterval(real a, real b) et OmitTickIntervals(real[] a, real[] b) peuvent servir à enlever des graduations, ainsi que leurs labels.
    NoZero est une abréviation pour OmitTick(0).

  • Size et size : taille des graduations principales et secondaires.

  • extend : étend les graduations. Permet de tracer des grilles.

  • pen pTick et ptick : stylos pour le tracé des traits de graduation.
Image non disponible
Image non disponible
Code 58
Sélectionnez
import graph;
unitsize(1cm);
xaxis(L="$x$", axis=YZero,
      xmin=-3, xmax=3, p=bp+blue,
      ticks=LeftTicks(ticklabel=OmitFormat(1),
                endlabel=false,Step=1,step=.5,
                end=false,modify=OmitTick(-2),
                pTick=bp+red,ptick=bp+.8green),
      arrow=Arrow);
Code 59
Sélectionnez
import graph;
unitsize(1cm);
real[] tabT={-2,0,1}, tabt={-1.5,-.5,.5};
xaxis(L="$x$", axis=YZero(extend=true),
      xmin=-3, xmax=3, p=bp+blue,
      ticks=Ticks(Ticks=tabT, ticks=tabt,
               pTick=bp+red,ptick=bp+.8green),
      arrow=Arrow, above=false);

Il est aussi possible de spécifier l'emplacement des graduations à l'aide d'un tableau de réels à l'aide de la routine (voir le code 59, valable aussi pour LeftTicks et RightTicks) :

 
Sélectionnez
ticks Ticks(Label format="", ticklabel ticklabel=null,
            bool beginlabel=true, bool endlabel=true,
            real[] Ticks, real[] ticks=new real[],
            real Size=0, real size=0, bool extend=false,
            pen pTick=nullpen, pen ptick=nullpen)

De la même façon que xaxis est défini :

 
Sélectionnez
void yaxis(picture pic=currentpicture, Label L="", axis axis=XZero,
           real ymin=-infinity, real ymax=infinity, pen p=currentpen,
           ticks ticks=NoTicks, arrowbar arrow=None, bool above=false,
           bool autorotate=true);

Les paramètres sont similaires à ceux de xaxis. On notera pour le type axis les valeurs Left, Right et LeftRight.

Il est possible de fixer les valeurs xmin, xmax, ymin et ymax par la routine :

 
Sélectionnez
xlimits(picture pic=currentpicture, real min=-infinity,
        real max=infinity, bool crop=NoCrop);

et la routine ylimits.

Le booléen crop=Crop sert à couper les parties de la figure qui dépassent les limites.

Image non disponible
Image non disponible
Code 60
Sélectionnez
import graph;
unitsize(1cm);
xaxis(L="$x$", axis=YZero,
      xmin=-3, xmax=3, p=bp+blue,
      ticks=Ticks(endlabel=false,
                  beginlabel=false,
                  Step=1,step=.5,
                  end=false,pTick=bp+red,
                  ptick=bp+.8green),
      arrow=Arrow);

yaxis(L="$y$", axis=LeftRight,
      ymin=-1, ymax=3, p=bp+purple,
      ticks=Ticks(beginlabel=false,
                  Step=1,step=.25,
                  pTick=bp+red,
                  ptick=bp+.8green),
      arrow=Arrow);
Code 61
Sélectionnez
import graph;
unitsize(1cm);
xlimits(-3, 3);
ylimits(-1, 3);
xaxis(L="$x$",axis=BottomTop,p=bp+blue,
      ticks=Ticks(Step=1,step=.5,extend=true,
                  pTick=bp+red,
                  ptick=bp+dotted+.8green),
      arrow=Arrow);

yaxis(L="$y$",axis=LeftRight,p=bp+purple,
      ticks=Ticks(Step=1,step=.5,extend=true,
                  pTick=bp+red,
                  ptick=bp+dotted+.8green),
      arrow=Arrow);

Pour des axes déportés, on peut utiliser les routines suivantes :

 
Sélectionnez
void xequals(picture pic=currentpicture, Label L="", real x,
             bool extend=false, real ymin=-infinity, real ymax=infinity,
             pen p=currentpen, ticks ticks=NoTicks, bool above=true,
             arrowbar arrow=None);

void yequals(picture pic=currentpicture, Label L="", real y,
             bool extend=false, real xmin=-infinity, real xmax=infinity,
             pen p=currentpen, ticks ticks=NoTicks, bool above=true,
             arrowbar arrow=None);


void axes(picture pic=currentpicture, Label xlabel="", Label ylabel="",
          pair min=(-infinity,-infinity), pair max=(infinity,infinity),
          pen p=currentpen, arrowbar arrow=None, bool above=false);

Voir le code 65. Dans cet exemple, les axes sont tracés dans une image séparée, qui est ajoutée à currentpicture à la fin.

Image non disponible
Image non disponible
Code 62
Sélectionnez
import graph;
unitsize(1cm);
xlimits(17,23); ylimits(52,55);
xequals(pic=currentpicture,L="$y$",x=17,
        ticks=Ticks(Step=1,step=.5,end=false),
        arrow=Arrow(HookHead));

yequals(pic=currentpicture,L="$x$",y=52,
        ticks=Ticks(Step=1,step=.5,end=false),
        arrow=Arrow(HookHead));
Code 63
Sélectionnez
import graph;
unitsize(x=1cm, y=.5cm);
xlimits(-1, 5); ylimits(-2, 2);
xaxis(BottomTop, Ticks("%",extend=true,
      pTick=linewidth(.5pt),ptick=dotted));
yaxis(LeftRight, Ticks("%",extend=true,
      pTick=linewidth(.5pt),     ptick=dotted));
xequals(Label("$y$",align=2NW), 0,
        p=linewidth(bp), Arrow(2mm));
yequals(Label("$x$",align=2SE), 0,
        p=linewidth(bp), Arrow(2mm));
labelx(Label("$1$",UnFill), 1);
labely(Label("$1$",UnFill), 1);
dot("$O$",(0,0),2SW);
Image non disponible
Image non disponible
Code 64
Sélectionnez
import graph;
unitsize(1cm);
xlimits(-1,6); ylimits(-1,3);
xaxis(L="$x$", p=bp+blue,
      ticks=Ticks(NoZero,endlabel=false,
                  beginlabel=false,Step=1,step=.5,
                  begin=false,end=false),
      arrow=Arrow(TeXHead));
yaxis(L="$y$", p=bp+blue,
      ticks=Ticks(NoZero,beginlabel=false,
                  Step=1,step=.5,
                  begin=false,end=false),
      arrow=Arrow(TeXHead));
labelx("$O$",0,2*SW,blue);
xequals(pic=currentpicture,L="$Y$",x=3,
        p=brown+dashed,ticks=NoTicks,
        arrow=Arrow(HookHead));
yequals(pic=currentpicture,L="$X$",y=1,
        p=brown+dashed,ticks=NoTicks,
        arrow=Arrow(HookHead));
labelx("$A$",(3,1),2*SW,brown);
xtick("$1$",(4,1),size=1mm,brown);
xtick(dir=S,(4,1),size=1mm,brown);
ytick("$1$",(3,2),size=1mm,brown);
ytick(dir=W,(3,2),size=1mm,brown);
Code 65
Sélectionnez
import graph;
unitsize(1cm);
xlimits(-1,6); ylimits(-1,3);
xaxis(L="$x$", p=bp+purple,
      ticks=Ticks(NoZero,endlabel=false,
                  beginlabel=false,Step=1,step=.5,
                  begin=false,end=false),
      arrow=Arrow(TeXHead));
yaxis(L="$y$", p=bp+purple,
      ticks=Ticks(NoZero,beginlabel=false,
                  Step=1,step=.5,
                  begin=false,end=false),
      arrow=Arrow(TeXHead));
labelx("$O$",0,2*SW,purple);
picture pic;
unitsize(pic,1cm);
axes(pic, xlabel="$X$", ylabel="$Y$",
     min=(-4,-2), max=(3,2),p=dashed+red,
     arrow=Arrow(HookHead));
labelx(pic,"$A$",(0,0),2*SW,red);
xtick(pic,"$1$",1,size=1mm,red);
xtick(pic,dir=S,1,size=1mm,red);
ytick(pic,"$1$",1,size=1mm,red);
ytick(pic,dir=W,1,size=1mm,red);
add(pic.fit(),(3,1));

Les routines suivantes permettent de placer manuellement des graduations :

 
Sélectionnez
void xtick(picture pic=currentpicture, Label L="", explicit pair z,
           pair dir=N, string format="",
           real size=Ticksize, pen p=currentpen);
           void xtick(picture pic=currentpicture, Label L="", real x,
           pair dir=N, string format="",
           real size=Ticksize, pen p=currentpen);

De la même façon que xtick est défini ytick.

 
Sélectionnez
void tick(picture pic=currentpicture, pair z,
          pair dir, real size=Ticksize, pen p=currentpen);
          void labelx(picture pic=currentpicture, Label L="", explicit pair z,
          align align=S, string format="", pen p=nullpen);
          void labelx(picture pic=currentpicture, Label L="", real x,
          align align=S, string format="", pen p=nullpen);
          void labelx(picture pic=currentpicture, Label L,
          string format="", explicit pen p=currentpen);

De la même façon que labelx est défini labely.

VI-D-2. Représentations de fonctions

Plusieurs routines permettent de définir un graphe. Seules les plus utiles pour débuter seront vues (voir la documentation officielle pour les autres).

 
Sélectionnez
guide graph(picture pic=currentpicture, real f(real), real a, real b,
            int n=ngraph, real T(real)=identity,
            interpolate join=operator --);

Retourne le graphe de la fonction f sur l'intervalle kitxmlcodeinlinelatexdvp\left[T(a) ;T(b)\right]finkitxmlcodeinlinelatexdvp , basé sur n points (100 par défaut) régulièrement espacés dans kitxmlcodeinlinelatexdvp\left[a ;b\right]finkitxmlcodeinlinelatexdvp .

Image non disponible
Code 66
Sélectionnez
import graph;
unitsize(1cm);
xaxis("$x$", Ticks(scale(.7)*Label(), NoZero),Arrow(2mm));
yaxis("$y$", Ticks(scale(.7)*Label(), NoZero, beginlabel=false, endlabel=false,
      begin=false, end=false), Arrow(2mm));
labelx(scale(.7)*"$O$",0,SW);
real f(real x) {return 4*x/(x^2+1);}
draw(graph(f,-5.5,5.5),bp+purple);
label("$y=\frac{4x}{x^2+1}$",(4,f(4)),1.5N,purple);
label("anguin\'ea",(-3.5,1.5),purple);
label(scale(.8)*"(ou cubique serpentine)",(-3.5,1),purple);
 
Sélectionnez
guide graph(picture pic=currentpicture, real x(real), real y(real),
            real a, real b, int n=ngraph, real T(real)=identity,
            interpolate join=operator --);

Retourne la courbe paramétrée kitxmlcodeinlinelatexdvp\left(x(t);y(t)\right)\quad\forall t \in \left[T(a);T(b)\right]finkitxmlcodeinlinelatexdvp .

Image non disponible
Code 67
Sélectionnez
import graph;
unitsize(1cm);
usepackage("inputenc","utf8"); usepackage("icomma");
xaxis("$x$", Ticks(scale(.7)*Label(), NoZero),Arrow(2mm));
yaxis("$y$", Ticks(scale(.7)*Label(), NoZero, beginlabel=false, endlabel=false,
      begin=false, end=false), Arrow(2mm));
labelx(scale(.7)*"$O$",0,SW);
real x(real t) {return 2*cos(t)+1.5*cos(2*t);}
real y(real t) {return 2*sin(t)-1.5*sin(2*t);}
pen pg=royalblue;
draw(graph(x,y,0,2*pi),bp+pg);
label(scale(.6)*"$x(t)=2\cos(t)+1,5\cos(2t)$",(1.8,-2),1.5N,pg);
label(scale(.6)*"$y(t)=2\sin(t)-1,5\sin(2t)$",(1.8,-2),pg);
 
Sélectionnez
guide polargraph(picture pic=currentpicture, real f(real), real a,
                 real b, int n=ngraph, interpolate join=operator --);

Retourne le graphe de la fonction kitxmlcodeinlinelatexdvpffinkitxmlcodeinlinelatexdvp en coordonnées polaires sur l'intervalle kitxmlcodeinlinelatexdvp[a;b].finkitxmlcodeinlinelatexdvp

Image non disponible
Code 68
Sélectionnez
import graph;
size(6cm);
usepackage("inputenc","utf8");
xaxis(Ticks("%", NoZero, Step=1, step=.5), Arrow(2mm));
yaxis(Ticks("%", NoZero, Step=1, step=.5), Arrow(2mm));
labelx(scale(.7)*"$O$",0,SW);
real r(real t) {return 1+2*sin(t/2);}
pen pg=deepmagenta;
draw(polargraph(r,0,4*pi,n=400),bp+pg);
label(scale(.8)*"$r=1+2\sin\left(\theta/2\right)$",(-1.5,-1),pg);
label("néphroïde de Freeth",(-.5,1.3),pg);

Remarque : Fonctions non définies en certaines valeurs

Deux possibilités ici :

  1. « enlever » les valeurs interdites : pour l'exemple, considérons la fonction

    kitxmlcodelatexdvpf : x \longmapsto \dfrac{-1}{x^2-4x+3}.finkitxmlcodelatexdvp


    Cette fonction est définie sur

    kitxmlcodelatexdvp\mathbb{R}\setminus\{1;3\}.finkitxmlcodelatexdvp

    La courbe sera découpée en trois graphes,

    kitxmlcodelatexdvp\mathcal{C_1},\ \mathcal{C_2}\ \mathrm{et}\ \mathcal{C_3}finkitxmlcodelatexdvp

    qui éviteront soigneusement les valeurs 1 et 3.

    Image non disponible
     
    Sélectionnez
    import graph;
    import contour;
    usepackage("mathrsfs");
    unitsize(x=1cm,y=1cm);
    
    transform ec=scale(.8);
    xaxis(ec*"$x$", Ticks(ec*Label(), NoZero), Arrow(2mm));
    yaxis(ec*"$y$", Ticks(ec*Label(), NoZero), Arrow(2mm));
    labelx(ec*"$O$",0,SW);
    
    real f(real x) {return -1/(x^2-4*x+3);}
    path c1=graph(f,-2.8,.9); // on évite les valeurs
    path c2=graph(f,1.1,2.9); // interdites
    path c3=graph(f,3.1,6.8); //
    draw(c1^^c2^^c3,bp+heavyred);
    ylimits(-2.9,2.9,Crop); // on coupe ce qui dépasse
    label("$\mathscr{C}_f$",(3,1.5),heavyred);
  2. utiliser le module contour et tracer la courbe comme une ligne de niveau.
    On utilise la routine suivante :

     
    Sélectionnez
    guide[][] contour(real f(real, real), pair a, pair b,
                      real[] c, int nx=ngraph, int ny=nx,
                      interpolate join=operator--, int subsample=1)
  3. Pour notre exemple, la courbe kitxmlcodeinlinelatexdvp\mathcal{C_f}finkitxmlcodeinlinelatexdvp a pour équation kitxmlcodeinlinelatexdvpy=\dfrac{-1}{x^2-4x+3}.finkitxmlcodeinlinelatexdvp
    D'où l'on tire : kitxmlcodeinlinelatexdvpy\times (x^2-4x+3)=-1.finkitxmlcodeinlinelatexdvp
    On considérera donc la fonction kitxmlcodeinlinelatexdvpF(x , y)= y(x^2-4x+3)finkitxmlcodeinlinelatexdvp et on tracera la ligne de niveau -1.
  • f : fonction de deux variables réelles.
  • a et b : les sommets de la diagonale du domaine rectangulaire.
  • c : tableau contenant les valeurs des lignes de niveau.
  • nx et ny : nombre de subdivisions dans les directions x et y (détermine la précision).
  • join : l'opérateur d'interpolation (-- ou ..).
  • subsample : nombre de points intérieurs à inclure dans chaque carré de la grille (en plus des points sur le bord).
Image non disponible
Code 70
Sélectionnez
import graph;
import contour;
usepackage("mathrsfs");
unitsize(x=1cm,y=1cm);
transform ec=scale(.8);

xaxis(ec*"$x$", Ticks(ec*Label(), NoZero), Arrow(2mm));
yaxis(ec*"$y$", Ticks(ec*Label(), NoZero), Arrow(2mm));
labelx(ec*"$O$",0,SW);

real F(real x, real y) {return y*(x^2-4*x+3);}
draw(contour(F,(-2.8,-2.9),(6.8,2.9),new real[] {-1}),bp+deepcyan);
label("$\mathscr{C}_f$",(3,1.5),deepcyan);

Voir aussi le code 71

VI-D-3. Extension graph_pi

Cette extension de Philippe Ivaldi apporte bon nombre d'outils intéressants.

Elle peut être téléchargée à cette adresse : git.piprime.fr/?p=asymptote/pi-packages.git;a=tree, lien snapshot, et placée dans le dossier $HOME/.asy.

Pour une utilisation avec git, voir : forum.mathematex.net/asymptote-f34/version-2-10-et-graph-pi-t13226.html#p127606.

Les modules graph, markers et base_pi (voir à l'adresse ci-dessus) sont chargés par graph_pi, ainsi que le package kitxmlcodeinlinelatexdvp\LaTeXfinkitxmlcodeinlinelatexdvp mathrsfs.

Axes et repères :

 
Sélectionnez
void graphicrules(picture pic=currentpicture, real unit=1cm,
                  real xunit=unit != 0 ? unit : 0,
                  real yunit=unit != 0 ? unit : 0,
                  real xmin=-infinity, real xmax=infinity,
                  real ymin=-infinity, real ymax=infinity,
                  bool crop=NoCrop, bool xcrop=crop, bool ycrop=crop)

Passe les dimensions du graphique à cartesianaxis, grid, et millimeterpaper (voir ci-après).

 
Sélectionnez
void cartesianaxis(picture pic=currentpicture,
                   Label Lx=Label("$x$",align=2S),
                   Label Ly=Label("$y$",align=2W),
                   real xmin=-infinity, real xmax=infinity,
                   real ymin=-infinity, real ymax=infinity,
                   real extrawidth=1, real extraheight=extrawidth,
                   pen p=currentpen,
                   ticks xticks=Ticks("%",pTick=nullpen, ptick=grey),
                   ticks yticks=Ticks("%",pTick=nullpen, ptick=grey),
                   bool viewxaxis=true,
                   bool viewyaxis=true,
                   bool above=true,
                   arrowbar arrow=Arrow)

Trace l'axe des abscisses, des ordonnées ou les deux (viewxaxis et viewyaxis qui prennent les valeurs true ou false). extrawidth est la longueur rajoutée à l'axe des abscisses par rapport à xmin et xmax. On a la même chose avec extraheight pour l'axe des ordonnées.

Image non disponible
Code 71
Sélectionnez
import graph_pi;
import contour;
graphicrules(xunit=.5cm, yunit=2cm, xmin=-14.8, xmax=14.8, ymin=-1.9, ymax=1.9);
cartesianaxis(extrawidth=0,xticks=Ticks(NoZero), yticks=Ticks(NoZero), Arrow(2mm));
labelx("$O$",0,SW);
real F(real x, real y) {return x*y-cos(x);}
draw(contour(F,(-14.8,-1.9),(14.8,1.9),new real[] {0}),bp+darkgreen);
label("$y=\displaystyle\frac{\cos x}{x}$",(3,1),darkgreen);
 
Sélectionnez
void labeloij(picture pic=currentpicture,
              Label Lo=Label("$O$",NoFill),
              Label Li=Label("$\overrightarrow{\imath}$",NoFill),
              Label Lj=Label("$\overrightarrow{\jmath}$",NoFill),
              pen p=scale(2)*currentpen,
              pair diro=SW, pair diri=labelijmargin*S, pair dirj=labelijmargin*1.5*W,
              filltype filltype=NoFill, arrowbar arrow=Arrow(2mm),
              marker marker=dot)

Trace le repère kitxmlcodeinlinelatexdvp(O; \vec{\imath}; \vec{\jmath}).finkitxmlcodeinlinelatexdvp

 
Sélectionnez
void labeloIJ(picture pic=currentpicture,
              Label Lo=Label("$O$",NoFill),
              Label LI=Label("$I$",NoFill),
              Label LJ=Label("$J$",NoFill),
              pair diro=SW, pair dirI=labelIJmargin*S, pair dirJ=labelIJmargin*W,
              pen p=currentpen,
              filltype filltype=NoFill,
              marker marker=dot)

Trace le repère kitxmlcodeinlinelatexdvp(O;I;J).finkitxmlcodeinlinelatexdvp

 
Sélectionnez
void grid(picture pic=currentpicture,
          real xmin=pic.userMin.x, real xmax=pic.userMax.x,
          real ymin=pic.userMin.y, real ymax=pic.userMax.y,
          real xStep=1, real xstep=.5,
          real yStep=1, real ystep=.5,
          pen pTick=currentpen, pen ptick=grey, bool above=false)

Trace une grille.

Image non disponible
Code 72
Sélectionnez
import graph_pi;
graphicrules(xunit=1cm, yunit=2cm, xmin=-5, xmax=5, ymin=0, ymax=1.5);
grid(pTick=currentpen,ptick=dotted);
cartesianaxis(xticks=Ticks("%"), yticks=Ticks(NoZero,Step=1,step=.5), Arrow(2mm));
labeloij();
real f(real x) {return 1/(1+x^2);}
draw(graph(f), bp+fuchsia);
label("$y=\displaystyle\frac{1}{1+x^2}$",(1,f(1)),NE,fuchsia);
label("Cubique d'Agnesi",(-3,1.2),fuchsia);
 
Sélectionnez
picture millimeterpaper(picture pic=currentpicture, pair O=(0,0),
                        real xmin=infinity, real xmax=infinity,
                        real ymin=infinity, real ymax=infinity,
                        pen p=.5bp+orange)

Grille sous forme de papier millimétré.

 
Sélectionnez
ticklabel labelfrac(real ep=1/10^5, real factor=1,
                    string symbol="",
                    bool signin=false, bool symbolin=true,
                    bool displaystyle=false,
                    bool zero=true)

Ce ticklabel permet d'écrire les graduations sous forme de fractions. Attention, base_pi doit être dans le dossier $HOME/.asy.

Image non disponible
 
Sélectionnez
import graph_pi;
marker croix=marker(scale(4)*rotate(45)*cross(4),linewidth(bp));
pen bpd=bp+brown+linetype("4 4");
graphicrules(xunit=1cm, yunit=3cm, xmin=-6.5, xmax=6.5, ymin=-1.17, ymax=1.17);
add(millimeterpaper(p=1bp+orange),(0,0));
labeloij(Lj=Label(""));
cartesianaxis(Lx=Label("$x$",align=2N),extrawidth=0,
              xticks=Ticks(Label(Fill(white)),
                           labelfrac(factor=pi,symbol="\pi",symbolin=true,
                                     zero=false),Step=pi/2, step=pi/4),
              yticks=Ticks(Label(Fill(white)),
                           labelfrac(zero=false),Step=.5));
// Définition des fonctions
real f(real x) {return cos(x);}
real g(real x) {return sin(x);}
// Tracé de courbe
draw(graph(f),bp+blue);
draw(graph(g),bpd);
// Points sur les courbes
real l=-2pi;
for(int i=0; i<17; ++i) {
    draw((l,f(l)),croix);
    draw((l,g(l)),croix);
    l=l+pi/4;
}
label("$\mathscr{C}_f : y=\cos(x)$",(2.5,f(2.5)),W,blue);
label("$\mathscr{C}_g : y=\sin(x)$",(2.5,g(2.5)),NE,brown);

Représentations graphiques de suites :

 
Sélectionnez
recursiveroutime recursiveoption(Label L="u",
                                 bool labelbegin=true,
                                 bool labelend=true,
                                 bool labelinner=true,
                                 bool labelalternate=false,
                                 string format="",
                                 int labelplace=onX,
                                 pen px=nullpen,
                                 pen py=nullpen,
                                 bool startonyaxis=false,
                                 arrowbar circuitarrow=None,
                                 marker automarker=marker(cross(4)),
                                 marker xaxismarker=nomarker,
                                 marker yaxismarker=nomarker,
                                 marker xmarker=nomarker,
                                 marker fmarker=nomarker)

Les options du graphique :

  • L : le nom de la suite (à taper sans $).
  • labelbegin : si la valeur est true, le premier terme est placé.
  • labelend : même chose pour le dernier terme.
  • abelinner : si la valeur est true, les termes compris entre le premier et le dernier sont placés.
  • labelalternate : si la valeur est true, les termes sont alternés par rapport à l'axe.
  • format : le format d'affichage de la valeur. Par exemple "%.2f" (2 chiffres après la virgule).
  • labelplace : emplacement des termes : onX, onY, ou onXY.
  • px et py : stylos pour les tracés des traits de lecture.
  • startonyaxis : comme son nom l'indique...
  • circuitarrow : flèches sur le « circuit ».
  • Pour tous les marker, voir le code 75.

recursivegraph recursivegraph(real F(real), real u0, int n0=0, int n)

« Graphe » de la suite : kitxmlcodeinlinelatexdvpu0finkitxmlcodeinlinelatexdvp est le premier terme, kitxmlcodeinlinelatexdvpn0finkitxmlcodeinlinelatexdvp est l'indice du premier terme et kitxmlcodeinlinelatexdvpnfinkitxmlcodeinlinelatexdvp pour spécifier le nombre de termes placés sur le graphique (le dernier terme placé est celui d'indice kitxmlcodeinlinelatexdvpn-1finkitxmlcodeinlinelatexdvp ).

 
Sélectionnez
void draw(picture pic=currentpicture, Label L="", recursivegraph g,
          recursiveroutime lr=DefaultRecursiveOption, align align=NoAlign,
          pen p=currentpen, arrowbar arrow=None, arrowbar bar=None,
          margin margin=NoMargin, Label legend="", marker marker=nomarker)
Image non disponible
Code 74
Sélectionnez
import graph_pi;
usepackage("amsmath");
graphicrules(xunit=1cm, yunit=1cm, xmin=-.4, xmax=8.9, ymin=-.4, ymax=7.9);
cartesianaxis(extrawidth=0,xticks=Ticks("%"),yticks=Ticks("%"));
label("$0$",(0,0),2*SW);labely("$1$",1,1.5W);
real f(real x){return 2*sqrt(x)+1;}
draw(graph(f,0,8.9,n=400),bp+purple);
draw(graph(new real(real x){return x;},0,7.9),bp+red);
draw(recursivegraph(f,u0=1,n0=1,n=6),
                    recursiveoption(L="v", labelplace=onXY),
                    bp+heavymagenta);
label("$y=2\sqrt{x}+1$",(7.5,f(7.5)),3S,purple);
label("$y=x$",(7,7),2W,red);
label("$\left\{\begin{aligned}&v_1=1\\&v_{n+1}=2\sqrt{v_n}+1
               \end{aligned}\right.$",(2.5,7));
Image non disponible
Code 75
Sélectionnez
import graph_pi;
usepackage("amsmath");usepackage("icomma");
graphicrules(xunit=2cm, yunit=2cm, xmin=-.4, xmax=4.4, ymin=-.4, ymax=3.4);
cartesianaxis(extrawidth=0,xticks=Ticks(NoZero),yticks=Ticks(NoZero));
label("$0$",(0,0),2*SW);
real f(real x){return x/2+1/x;}
draw(graph(f,.1,4.4),bp+deepblue);
draw(graph(new real(real x){return x;}),bp+red);
ylimits(-.4,3.4,Crop);
draw(recursivegraph(f,3.5,n=4), recursiveoption(L=scale(.7)*"u",
                                labelbegin=true, labelend=true,
                                labelinner=true, labelalternate=true,
                                format="\approx %.1f", labelplace=onX,
                                px=dashed, py=nullpen,
                                startonyaxis=false, circuitarrow=MidArrow(3mm),
                                automarker=marker(scale(5)*cross(4),blue),
                                xaxismarker=dot(orange), yaxismarker=nomarker,
                                xmarker=dot(green), fmarker=dot(magenta)),bp+heavycyan);
label("$y=\frac{x}{2}+\frac{1}{x}$",(.5,f(.5)),E,deepblue);
label("$y=x$",(3,3),SE,red);
label(scale(.9)*"$\left\{\begin{aligned}&u_0=3,5\\
                 &u_{n+1}=\frac{u_n}{2}+\frac{1}{u_n}
                 \end{aligned}\right.$",(.75,3),E);
 
Sélectionnez
void graphpoint(picture pic=currentpicture,
                Label L="",
                real f(real), real xCoordinate,
                real xmin=0, real ymin=0,
                int draw=onXY,
                pen px=nullpen, pen py=px,
                arrowbar arrow=None, arrowbar bar=None,
                margin marginy=NoMargin, margin marginx=NoMargin,
                bool extend=false, bool extendx=extend, bool extendy=extend,
                Label legendx="", Label legendy="",
                marker markerx=nomarker, marker markery=nomarker)

path tangent(path g, real x, pathb=box(userMin(currentpicture),userMax(currentpicture)))

void addtangent(picture pic=currentpicture,
                path g,//Point on the path g
                pair pt,// real x (x-Coordinate) est aussi défini
                real size=infinity,//ABSOLUTE size of the tangent line
                bool drawright=true,//Draw the tangent at the right
                bool drawleft=true,//... left
                pair v=(infinity,infinity),//A finite value forces the value of the derivative
                pair vr=v,//A finite value forces the value of the derivative at right
                pair vl=v,//A finite value forces the value of the derivative at left
                arrowbar arrow=null,//null=automatic determination
                margin margin=NoMargin,//Useful with size=infinity
                Label legend="",
                pen p=currentpen,
                real dt=2,
                bool differentiable=true)
Image non disponible
Code 76
Sélectionnez
import graph_pi;
graphicrules(xunit=1cm, yunit=1cm, xmin=-4, xmax=3, ymin=-.5, ymax=5);
cartesianaxis(xticks=RightTicks(NoZero), yticks=LeftTicks(NoZero,Step=1));
grid(pTick=paleblue,ptick=paleblue);
labeloij();

real f(real x){return exp(x);}
path Cf=graph(f,n=200);
draw(Cf, bp+darkbrown);

addtangent(Cf,x=0,size=1cm,heavymagenta);
addtangent(Cf,x=1,size=1cm,heavymagenta);
graphpoint(f,1,px=dashed+blue);

dot((1,f(1))); dot((0,f(0)));
labely("e",f(1),blue);
ylimits(-1,5.5,Crop);
label("$\mathscr{C}_\mathrm{exp}$",(1.5,f(1.5)),E,darkbrown);

VI-E. animation

Ce module permet de faire des animations aux formats gif et mpeg en utilisant convert d'ImageMagick (qui doit donc être installé sur l'ordinateur), ainsi qu'au format pdf (animations visibles avec Acrobat Reader).

Pour obtenir un gif par exemple, il suffit de compiler avec l'option -f gif :

asy -f gif

ou de rajouter dans le fichier asy

settings.outformat="gif";

En pratique, le module animate.asy importe le module animation.asy et le package animate.sty. Pour plus d'éclaircissements il faudra donc se référer au fichier animation.asy, ainsi qu'à la documentation du package kitxmlcodeinlinelatexdvp\LaTeXfinkitxmlcodeinlinelatexdvp animate.sty (qui est donc requis).

VI-E-1. Création d'animations autonomes

Les principales routines utilisées ici sont :

void erase(picture pic=currentpicture);

qui efface l'image,

void save()

qui sauvegarde l'image à l'endroit où elle est utilisée,

void restore()

qui restaure (c'est facile l'anglais !) l'image au point où elle a été sauvegardée par save(), et enfin

void add(picture pic=currentpicture, enclosure enclosure=NoBox)

qui ajoute l'image à l'animation.

Un exemple : construction de la médiatrice d'un segment. (Pour voir l'animation, il faut utiliser Acrobat Reader.)

Image non disponible
Code 77
Sélectionnez
import geometry;
import animate;
settings.tex="pdflatex";
settings.outformat="pdf";
size(15cm,0);
point A=(0,0), B=(3,-2), lab=(6,1);
circle cA=circle(A,2.5), cB=circle(B,2.5);
point[] int=intersectionpoints(cA,cB);
segment seg=segment(A,B);
line med=line(int[0],int[1]);
animation Anim;
// --------------------------------------------
// Étape 0
draw(seg,bp+heavygreen);
dot("$A$",A,unit(A-B)); dot("$B$",B,unit(B-A));
Anim.add();
// Étape 1
draw(cA,bp+blue);
draw(cB,bp+blue);
Anim.add();
// Étape 2
save(); // tout ce qu'il y a avant sera conservé dans la suite
label("\begin{minipage}{4cm}
      On trace deux cercles\\
      de m\^eme rayon.\end{minipage}",lab,E);
draw(lab..controls (4,2) and (3,2)..angpoint(cA,45),Arrow());
draw(lab..controls (5.5,1) and (4.5,1)..angpoint(cB,60),Arrow());
Anim.add();
restore();
// Etape 3
save();
label("\begin{minipage}{4cm}
      Deux points\\
      \'equidistants\\
      de $A$ et $B$.\end{minipage}",lab,E);
draw(lab..controls (3,.5) and (2,-.5)..int[0],Arrow());
draw(lab..controls (5,1) and (4.5,1)..int[1],Arrow());
dot(int[0],heavyred); dot(int[1],heavyred);
Anim.add();
restore();
// Étape 4
save();
draw(med,bp+heavyred);
label("\begin{minipage}{4cm}
      M\'ediatrice de $\left[AB\right]$\end{minipage}",lab,E,heavyred);
      draw(lab..controls (5,1.5) and (4,1.6)..relpoint(med,1.4),Arrow());
dot(int[0],heavyred); dot(int[1],heavyred);
Anim.add();
restore();
// --------------------------------------------
erase(); // permet d'éviter les effets de "décalage"
label(Anim.pdf("controls,step"));

Quelques sorties :

label(Anim.pdf("<options>",keep=true,multipage=false));

pour obtenir un pdf par image.

label(Anim.pdf("<options>",keep=true,multipage=true));

pour obtenir l'animation et le pdf multipage (pdf contenant une page par image).

label(Anim.pdf("<options>"));

pour l'animation uniquement.

Anim.movie();

pour obtenir un pdf multipage.

Anim.glmovie();

pour une sortie dans la fenêtre OpenGL, à compiler avec asy -V

Pour les options entre guillemets, ce sont les options du package animate.sty (il faut consulter sa documentation pour davantage de précisions). On trouve entre autres :

  • autoplay : démarre l'animation automatiquement.
  • loop : l'animation recommence en boucle.
  • controls : pour les boutons de contrôle (sinon, il faut cliquer sur l'animation pour la lancer).
  • buttonsize=<size>, buttonbg=<colour>, buttonfg=<colour> : mise en forme des boutons.
  • palindrome : l'animation s'exécute d'avant en arrière.
  • step : pas à pas.
  • width=..., height=..., depth=... : redimensionne l'animation.
  • scale=... : mise à l'échelle de l'animation.

Il est aussi possible de préciser le temps (en millisecondes) entre chaque image, par exemple :

label(Anim.pdf("controls",delay=50));

pour une image toutes les 50 millisecondes.

movie() peut aussi prendre des arguments, utile par exemple pour la création d'un gif (puisqu'il n'y aura pas de boutons de contrôle...). L'exemple ci-contre peut être compilé directement par : asy mongif.asy.

Code 78
Sélectionnez
import animation;
settings.outformat="gif";
size(100,100);
path c1=circle((0,0),1);
path c2=circle((0,.6),.4);
draw(c1,bp+purple);
animation Anim;
// -------------------------------
for(int i=0; i < 360; i+=10) 
{
    save();
    draw(rotate(i)*c2,bp+heavymagenta);
    Anim.add();
    restore();
}
// -------------------------------
Anim.movie(loops=3,delay=50);

VI-E-2. Inclure une animation externe dans un fichier .tex

L'animation doit être créée avec la sortie Anim.movie() (pdf multipage). Le package animate.sty va se charger de reconstituer l'animation à l'aide de la commande : \animategraphics[<options>]{<frame rate>}{<file basename>}{<first>}{<last>}

<file basename> est le nom de l'animation sans extension et <frame rate> est le nombre d'images par seconde. <first> et <last>, la première et dernière image.

Exemple :

 
Sélectionnez
\documentclass{article}
\usepackage{animate}
\begin{document}
\animategraphics[width=\linewidth,controls]{10}{animcos}{}{}
\end{document}
Code 79
Sélectionnez
// Animation réalisée avec l'aide de Gaétan Marris et Olivier Guibé
import graph_pi;
import animate;
settings.tex="pdflatex";
settings.outformat="pdf";
usepackage("fourier","upright");
real f(real x) {return cos(x);}
path Cf1=graph(f,0,pi,n=20,Hermite);
path Cf2=graph(f,-pi,pi,n=20,Hermite);
path Cf3=graph(f,pi,3pi,n=20,Hermite);
transform sc=scale(.8);
pen pinit=1.2bp+magenta, pf=1.2bp+.8blue, pvec=bp+deepgreen;

animation A;
// ------------------------------------------------------------------------------
void trace(path f, pen p,
           Label L="", real r=0, real per=2pi, pair NS=(0,0),
           pen pv=nullpen, arrowbar arrow=Arrow(HookHead,2mm)){
           draw(f,p);
           if (NS!=(0,0))
           draw(Label(sc*L,Fill(white),align=NS),(r,f(r))--(r+per,f(r+per)),pv,arrow);
}
graphicrules(xunit=1cm, yunit=1cm, xmin=-3pi, xmax=3pi, ymin=-1.5, ymax=1.5);
add(millimeterpaper(p=1bp+orange),(0,0));
labeloij(Lo=sc*"$O$",Li=sc*"$\overrightarrow{\imath}$",Lj=sc*"$\overrightarrow{\jmath}$");
cartesianaxis(xticks=Ticks(sc*Label(Fill(white)),
                           labelfrac(factor=pi,symbol="\pi",symbolin=true,
                                     zero=false),Step=pi/2, ptick=black),
              yticks=Ticks(sc*Label(Fill(white)),
                           labelfrac(zero=false),Step=1,step=.5));
A.add();
// ------------------------------------------------------------------------------
for (real p=-1; p<=1; p+=.1) {
     save();
     trace(Cf1,pinit);
     draw(xscale(-p)*Cf1,pinit);
     A.add();
     restore();
}
for (real t=0; t<=2pi; t+=pi/25) {
     save();
     trace(Cf2,pinit,"$2\pi \vec{\imath}$",.75,N,pvec);
     draw(shift(t,0)*Cf2,pf);
     A.add();
     restore();
}
for (real t=0; t<=2pi+pi/25; t+=pi/25) {
     save();
     trace(Cf2,pinit,"$2\pi \vec{\imath}$",.75,N,pvec);
     trace(Cf3,pf,"$-2\pi \vec{\imath}$",-pi,-2pi,S,pvec);
     draw(shift(-t,0)*Cf2,pf);
     A.add();
     restore();
}
erase();
A.movie();
Image non disponible

Pour voir l'animation, il faut utiliser Acrobat Reader.

VI-E-3. Inclure le code dans un fichier .tex

On se contentera ici de copier le code du fichier inlinemovie.tex de la galerie d'exemples du site officiel : asymptote.sourceforge.net/gallery/animations

 
Sélectionnez
\documentclass{article}
\usepackage[inline]{asymptote}
%\usepackage{asymptote}
\usepackage{animate}
\begin{document}
Here is an inline PDF movie, generated with the commands
\begin{verbatim}
pdflatex inlinemovie
asy inlinemovie-*.asy
pdflatex inlinemovie
\end{verbatim}
or equivalently,
\begin{verbatim}
latexmk -pdf inlinemovie
\end{verbatim}
\begin{center}
\begin{asy}
import animate;
animation A=animation("movie1");
real h=2pi/10;
picture pic;
unitsize(pic,2cm);
for(int i=0; i < 10; ++i) {
draw(pic,expi(i*h)--expi((i+1)*h));
A.add(pic);
}
label(A.pdf("controls",delay=50,keep=!settings.inlinetex));
\end{asy}
%Uncomment the following line when not using the [inline] package option:
%\ASYanimategraphics[controls]{50}{movie1}{}{}
\end{center}
And here is anasymptote one, clickable but without the control panel:
\begin{center}
\begin{asy}
import animate;
animation A=animation("movie2");
real h=2pi/10;
picture pic;
unitsize(pic,2cm);
for(int i=0; i < 10; ++i) {
    draw(pic,expi(-i*h)--expi(-(i+1)*h),red);
    A.add(pic);
}
label(A.pdf(keep=!settings.inlinetex));
\end{asy}
%Uncomment the following line when not using the [inline] package option:
%\ASYanimategraphics[controls]{10}{movie2}{}{}
\end{center}
\end{document}

VII. Remeciements Developpez

Nous remercions l'auteur Christophe GROSPELLIER de nous avoir permit de publier cet article, nous remercions aussi les membres de l'équipe : … pour la correction orthographique et … pour la relecture technique.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2014 Christophe GROSPELLIER. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.