Page 1 sur 1

Modification de la commande dot

MessagePosté: Lundi 24 Septembre 2007, 16:07
par MB
Bonjour, la commande dot d'Asymptote qui permet d'afficher des points utilise par défaut de petits disques. Après avoir regardé dans la documentation, je n'ai rien trouvé permettant d'utiliser une autre forme.
Comment faire pour que cette commande affiche par exemple une croix ?

Re: [Asymptote] Modification de la commande dot

MessagePosté: Mardi 25 Septembre 2007, 10:27
par OG
Bonjour

effectivement pas facile à trouver.
Il y a au moins deux solutions

1) utilisation de errorbars (voir http://asymptote.sourceforge.net/galler ... orbars.asy) qui permet sur un nuage de points de faire des croix mais attention uniquement direction horizontale/verticale

2) j'ai naïvement essayé draw et ça marche !

Code: Tout sélectionner
frame mark;
filldraw(mark,scale(0.8mm)*polygon(6),green,green);
draw(mark,scale(0.8mm)*cross(6),blue);
draw((0,0),marker(mark));


où ici (j'ai pompé) on définit un motif dans la frame mark qui est utilisée comme marker

Une autre solution ?

Edition de l'après-midi : solution 3
Il suffit de définir un "pen" et de faire dot(pair,pen). Par exemple

Code: Tout sélectionner
pen croix=makepen(scale(0.8mm)*cross(6))+red;
dot((10,10),croix);


Edition de fin d'après-midi. En fait je préparais des graphiques de fonctions étagées. Il semblerait que pour la solution
2), i.e. avec draw il y ait toujours un point d'affiché. Le remère est de spécifier un pen ip=invisible.
Pour la solution 3), tout le monde ne peut pas devenir un pen ! il semblerait que seuls les paths cycliques puissent être transformés en pen via makepen.

J'espère que c'est la dernière édition !

Cordialement
O.G.

Re: [Asymptote] Modification de la commande dot

MessagePosté: Mardi 25 Septembre 2007, 18:04
par MB
Merci OG, ça fonctionne très bien.
J'ai eu un peu de mal pour épaissir le trait pour les marques en croix, mais il suffit de faire jouer la second paramètre de la fonction cross.
Voici un exemple d'utilisation :

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

pen dot_cross=makepen(scale(1mm)*cross(4,0.15));

real r = 5;

pair pO = (0,0);
pair pA = (-r,0);
pair pB = (r,0);

dot(Label("$A$",align=W),pA,dot_cross);
dot(Label("$B$",align=E),pB,dot_cross);
dot(Label("$O$",align=S),pO,dot_cross);

draw(pA--pB);

pair pC_1 = rotate(360-47,pO)*(pA-(0.7,0));
pair pC_2 = rotate(360-67,pO)*pA;
pair pC_3 = rotate(360-108,pO)*(pA-(-1.2,0));
pair pC_4 = rotate(360-129,pO)*pA;
pair pC_5 = rotate(360-141,pO)*(pA-(-0.4,0));
pair pC_6 = rotate(360-154,pO)*(pA-(0.6,0));
pair pC_7 = rotate(360-206,pO)*(pA-(0.8,0));
pair pC_8 = rotate(360-245,pO)*pA;
pair pC_9 = rotate(360-315,pO)*(pA-(-1.4,0));

dot(Label("$C_1$",align=NW),pC_1,dot_cross);
dot(Label("$C_2$",align=NW),pC_2,dot_cross);
dot(Label("$C_3$",align=NE),pC_3,dot_cross);
dot(Label("$C_4$",align=NE),pC_4,dot_cross);
dot(Label("$C_5$",align=NE),pC_5,dot_cross);
dot(Label("$C_6$",align=NE),pC_6,dot_cross);
dot(Label("$C_7$",align=SE),pC_7,dot_cross);
dot(Label("$C_8$",align=SE),pC_8,dot_cross);
dot(Label("$C_9$",align=SW),pC_9,dot_cross);

shipout(bbox(xmargin=1mm,invisible));

Re: [Asymptote] Modification de la commande dot

MessagePosté: Jeudi 27 Septembre 2007, 00:46
par Ph. Ivaldi
Le problème avec cette utilisation de makepen est que dot((0,0),4bp+dot_cross) ne change en rien l'épaisseur du trait.
De même un dot((0,0),linecap(0)+dot_cross) ne change pas l'arrondi des extrémités.
Pourquoi pas une petite routine cross qui se rapproche au plus près de dot ?
Noter que la modification de "crossdot" (décommenter la ligne // crossdot=...) en cours de code modifie la sortie sur toute l'image.
Je ne sais pas si une telle routine aurait sa place dans geometry.asy, personnellement je n'aime les croix que sur les figures faites à la main.

Code: Tout sélectionner
size(10cm,0);

path[] crossdot=new path[] {scale(0.75mm)*(W--E), scale(0.75mm)*(N--S)};
void cross(picture pic=currentpicture, Label L, pair z, align align=NoAlign,
           string format=defaultformat, pen p=currentpen)
{
  Label L=L.copy();
  L.position(z);
  if(L.s == "") {
    if(format == "") format=defaultformat;
    L.s="("+format(format,z.x)+","+format(format,z.y)+")";
  }
  L.align(align,E);
  L.p(p);
  picture tpic;
  pic.add(new void(frame f, transform t) {
      for (int i=0; i < crossdot.length; ++i) {
      draw(f,shift(t*z)*transform(p)*crossdot[i],p);
      }
    },true);
  add(pic,L);
}

cross("A1", (0,0), N);
cross("A2", (1,0), N, rotate(45)*red);
cross("A3", (2,0), N, xscale(2)*black);
cross("A4", (3,0), N, bp+blue);
cross("A6", (4,0), 4N, scale(5)*(0.8*yellow));
cross("A7", (5,0), 4N, scale(5)*linecap(0));

picture pic;
dot(pic,"B1",(0,0), N);
dot(pic,"B2",(1,0), N, rotate(45)*red);
dot(pic,"B3",(2,0), N, xscale(2)*black);
dot(pic,"B4",(3,0), N, bp+blue);
dot(pic,"B6",(4,0), 4N, scale(5)*(0.8*yellow));
dot(pic,"B7",(5,0), 4N, scale(5)*linecap(0));
currentpicture.add(shift(S)*pic);

// crossdot=new path[] {scale(2mm)*shift(-sqrt(2)/2,-sqrt(2)/2)*subpath(unitcircle,0.2,1),
//                      scale(2mm)*shift(sqrt(2)/2,-sqrt(2)/2)*subpath(unitcircle,1,1.8)};

picture pic;
cross(pic,"C1",(0,0), N);
cross(pic,"C2",(1,0), N, rotate(45)*red);
cross(pic,"C3",(2,0), N, xscale(2)*black);
cross(pic,"C4",(3,0), N, bp+blue);
cross(pic,"C6",(4,0), 4N, scale(5)*(0.8*yellow));
cross(pic,"C7",(5,0), 4N, scale(5)*linecap(0));

currentpicture.add(shift(2S)*pic);

Re: [Asymptote] Modification de la commande dot

MessagePosté: Jeudi 27 Septembre 2007, 11:05
par OG
Cher Philippe

Je te reconnais bien ici : une solution plutôt qu'un bricolage et à 2h du matin !

Olivier

Re: [Asymptote] Modification de la commande dot

MessagePosté: Jeudi 27 Septembre 2007, 13:13
par Ph. Ivaldi
OG a écrit:Je te reconnais bien ici : une solution plutôt qu'un bricolage et à 2h du matin !

Bonjour Olivier,

Merci pour le compliment :oops: mais Je n'ai pas trop de mérite...
J'ai simplement recopié le code de dot en remplaçant le Draw(pic,z,dotsize(p)+p) par ce qu'il faut pour avoir une croix.
La vraie difficulté est de découvrir la routine transform(pen) qui renvoie la transformation appliquée à un stylo; elle n'est documentée nulle part (à ce que je sache) et elle est codée directement en C++.

Par exemple
Code: Tout sélectionner
pen p=scale(2)*red;
write(transform(p));

renvoie (0,0,2,0,0,2).

Asymptote a beaucoup de ressource mais la documentation est parfois succincte...

Re: [Asymptote] Modification de la commande dot

MessagePosté: Jeudi 27 Septembre 2007, 19:14
par MB
Ph. Ivaldi a écrit:Le problème avec cette utilisation de makepen est que dot((0,0),4bp+dot_cross) ne change en rien l'épaisseur du trait.


Oui en effet. C'est pour ça que j'ai eu du mal à trouver comment faire.

Ph. Ivaldi a écrit:Je ne sais pas si une telle routine aurait sa place dans geometry.asy, personnellement je n'aime les croix que sur les figures faites à la main.


Bah je pense que ça peut être utile moi (à moi en tout cas). :mrgreen:
Car en général on demande aux élèves de faire des croix et pas des "ronds" donc si on leur donne des figures c'est mieux de respecter ses propres consignes.