Modeste contribution (un rapporteur)

Tout ce qui concerne le langage Asymptote. Ce langage est utilisable sur le forum via les balises asy.
[participation réservée aux utilisateurs inscrits]
Règles du forum
Merci de soigner la rédaction de vos messages et de consulter ce sujet avant de poster. Pensez également à utiliser la fonction recherche du forum.
africatex

Modeste contribution (un rapporteur)

Message non lu par africatex »

Bonjour,

pour ceux qui travaillent en classe de 6e, voici un rapporteur relativement paramétrable.
A noter qu'il nécessite (j'aurais pu faire sans mais bon pourquoi se priver...) l'incontournable geometry_dev de Philippe Ivaldi.
Evidemment il est améliorable/optimisable, n'hésitez pas à proposer des modifications....

Code : Tout sélectionner

import geometry_dev;

void rapporteur(picture pic=currentpicture,
                real diametre=8cm,           // le diametre du rapporteur
                real taille1=1cm,            // la taille des "grands" segments
                real taille2=.5cm,           // la taille des "petits" segments
                real base=3mm,               // la base du rapporteur
                real coeflabels=.5,          // pour diminuer la taille des labels
                int direction=0,             // la direction dans laquelle est posée le rapporteur sur la feuille
                int div1=10,                 // le nombre de degrés séparant les divisions principales
                int div2=1,                  // le nombre de degrés séparant les divisions secondaires
                pair pO=(0,0))               // le centre du rapporteur est ici
{
real r1,r2;
r1=(2*taille1)/diametre;
r2=(2*taille2)/diametre;

unitsize(pic,diametre/2,0);

ellipse Ce=circle(pO,1);
arc bord=arc(Ce,direction,direction+180,fromCenter);
draw(pic,bord, black+linewidth(1bp));
draw(pic,pO-dir(direction)--(2*base/diametre*dir(direction-90))+pO-dir(direction)--(2*base/diametre*dir(direction-90))+pO+dir(direction)--dir(direction)+pO,black+linewidth(1bp));

for(int i=direction; i < direction+180; i=i+div1){
draw(pic,pO+dir(i)--pO+(dir(i)*(1-r1)));
draw(pic,scale(coeflabels)*Label((string) (i-direction)),pO+dir(i)*(1-r1),dir(i+180));
 for(int j=div2; j < div1; j=j+div2){
 draw(pic,pO+dir(i+j)--pO+(dir(i+j)*(1-r2)),red);
 }
draw(pic,pO+dir(i+.5*div1)--pO+(dir(i+.5*div1)*(1-.5*(r1+r2))),blue);
}
draw(pic,pO+dir(direction+180)--pO+(dir(direction+180)*(1-r1)));
draw(pic,scale(coeflabels)*Label((string) 180),pO+dir(direction+180)*(1-r1),dir(direction+360));

draw(pic,pO+(r1/2)*dir(direction)--pO+(r1/2)*dir(direction+180));
draw(pic,pO--pO+(r1/2)*dir(direction+90));
}

rapporteur(diametre=5cm,taille1=.8cm,taille2=.4cm,base=3mm,coeflabels=.7,direction=57,div1=20,div2=2,pO=(-2,0));
testé avec Debian (Lenny) + kile + asymptote 1.55

Africatex
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2238
Inscription : samedi 29 décembre 2007, 00:58

Re: [Asymptote] modeste contribution: un rapporteur

Message non lu par projetmbc »

Salut, merci.
Tu devrais mettre un petit fichier PDF d'exemples ici.
africatex

Re: [Asymptote] modeste contribution: un rapporteur

Message non lu par africatex »

Il est simple de générer des exemples: seule la dernière ligne est responsable du dessin.
Il suffit donc de compiler en faisant varier les différents paramètres de cette ligne pour en comprendre le sens.
C'est de cette manière qu'on comprend le mieux un bout de code, il me semble: sur le mode expérimental.
Ph. Ivaldi

Re: [Asymptote] modeste contribution: un rapporteur

Message non lu par Ph. Ivaldi »

Bonjour et merci pour cette contribution. Juste un petit reproche. Avec le code :

Code : Tout sélectionner

size(20cm);
draw(unitcircle);
rapporteur(diametre=5cm,taille1=.8cm,taille2=.4cm,base=3mm,coeflabels=.7,direction=57,div1=20,div2=2,pO=(0,0));
... le rapporteur a la même taille que le cercle, et ce n'est pas cohérent puisque le cercle doit mesurer 20cm de diamètre.
Pour remédier à ce problème il te faut utiliser le "deferred drawing". Voici ce que j'ai dépoussiéré de mon disque:

Code : Tout sélectionner

void rapporteur(picture pic=currentpicture, pair center, pair end,
                real width=2cm, real stick=1.5mm, real Stick=4mm,
                pen p=currentpen)
{
  path c1,c2;
  real radius=abs(center-end);
  pair bout=(radius,0);
  c1=(-radius,0)..(0,radius)..bout;
  /* pic.add(new void(frame f, transform t) { CODE }, bool exact=false)
     permet de déférer 'CODE' en dernier, au(x) moment(s) où la mise à
     l'échelle doit être effectuée.
     f est le canevas qui va recevoir l'image, t est la transformation
     qu'il faut appliquer aux objets dépendants de l'echelle (pas les
     labels ou les têtes de flèches par exemple). */
  pic.add(new void(frame f, transform t) {
      /* t est la transformation qui sera appliquée à tous les objets
         dont le taille relative dépend de l'echelle choisi (size ou
         unitsize). */
      picture tpic;
      // Ici on n'applique pas t à (width,0), il aura donc a une taille
      // absolue !
      pair tbout=t*bout-(width,0);
      c2=rotate(180)*tbout..rotate(90)*tbout..tbout;
      path C1=t*c1;
      draw(tpic,point(C1,0)--relpoint(C1,1));
      draw(tpic,C1,p);
      draw(tpic,c2,p);
      dot(tpic,(0,0),p);
      /* cherche une homothétie à appliquer aux labels pour qu'ils ne
       chevauchent pas les graduations. */
      picture lpic;
      label(lpic,"180",p);
      real sl=abs(max(lpic)-min(lpic))/abs(t*((radius,0)-radius*dir(10)));
      transform scl=scale(0.75/sl);
      for (int i=0; i <=180; ++i)
        {
          real tstick;
          tstick=(i%10 == 0) ? Stick : stick;
          pair dir=dir(i), ptt=t*(radius*dir);
          pair ptti=ptt-tstick*dir;
          draw(tpic,ptt--ptti,p);
          pair ptt1=ptt-width*dir, ptti1=ptt1+tstick*dir;
          draw(tpic,ptt1--ptti1,p);
          if(i%10 == 0 ) {
            /* Transform(p) récupère la transformation appliquée à p pour
               la transmettre aux labels.
               cela permet d'ajuster, si besoin, l'homothétie calculée
               bêtement.*/
            label(tpic,scl*transform(p)*rotate(i-90)*((string)i),
                  ptti-(ptti-ptti1)/4,p);
            label(tpic,scl*transform(p)*scale(0.75)*rotate(i-90)*
                  ((string)(180-i)),ptti1+3*(ptti-ptti1)/16,p);
          }
        }
      add(f,shift(t*center)*rotate(degrees(end-center))*tpic.fit());
    }, true);
  // En cas de débordement on ajuste la "bounding box" de pic.
  pic.addBox(min(c1),max(c1),min(currentpen),max(currentpen));
}

// // 8<------8<------8<------8<------8<------8<------8<------8<------8<------
size(0,6cm);
draw ((0,0)--(5,5));
rapporteur((0,0),(5,0));
draw ((0,0)--(5,0),1mm+red);
// // 8<------8<------8<------8<------8<------8<------8<------8<------8<------

// // 8<------8<------8<------8<------8<------8<------8<------8<------8<------
// // Rapporteur inversé
// size(0,6cm);
// draw ((0,0)--(5,5));
// rapporteur((0,0),(3,3), 0.8*red);
// rapporteur((0,0),(-3,-3), 0.8*blue);
// // 8<------8<------8<------8<------8<------8<------8<------8<------8<------

// // 8<------8<------8<------8<------8<------8<------8<------8<------8<------
// // Un gros rapporteur
// size(0,15cm);
// draw ((0,0)--(5,5));
// // scale(1.25) va augmenter la taille des labels
// rapporteur((0,0),(3,3), width=5cm, 0.8*(scale(1.25)*black));
Ici, le rayon abs(center-end) dépend de l'échelle utilisée mais la taille width en est indépendante.
C'est loin d'être parfait mais actuellement je n'ai pas trop le temps de faire mieux :?
africatex

Re: [Asymptote] Modeste contribution: un rapporteur

Message non lu par africatex »

Merci pour cette remarque.

Effectivement, ici, le dessin doit s'adapter aux dimensions du rapporteur, alors que l'inverse serait souhaitable!
Je vais réfléchir au problème....
Répondre