Page 1 sur 1

[Résolu]deferred drawing et 3D

Posté : ven. 9 avr. 2010, 20:15
par chellier
Bonjour,
J'essaie d'écrire une fonction pour la cotation de figures 3D, et j'ai un paramètre (d) qui doit placer la double-flèche à une certaine longueur du segment. Mais cette longueur n'est bien sûr pas celle que je veux...

Code : Tout sélectionner

unitsize(1cm);
//size(7cm,0);
import solids;
settings.render=0;
settings.prc=false;
currentprojection = orthographic(5,0,0);

// v direction normale à la flèche de cotation et au segment, si k!=1 le label change de côté
void cote3D(Label L="", triple A, triple B, real d=3mm, triple v, real k=1){
   transform3 T=shift(d/10*unit(v));
   triple A=A, B=B;
   path3 dist;
   triple a=T*A, b=T*B;
   if (k==1) {dist=a--b;}
   else {dist=b--a;}
   draw(L,dist,Arrows3);
   draw(a--A,dotted);draw(b--B,dotted);
}

triple A=(0,0,0), B=(0,4,3), v=(0,-3,4);
draw(A--B);
cote3D("$5$",A,B,d=5*cm,v,k=-1);


C'est pas existentielle, et je peux choisir une valeur de d qui convienne au jugé, mais j'aimerais faire mieux, si c'est possible :?
Une idée ? :roll:

Re: deferred drawing et 3D

Posté : ven. 9 avr. 2010, 21:10
par GM
Je ne réponds pas à ta demande pour ton script : je vais me contenter d'un copier-coller d'un exemple (qui date de deux ans) qu'il faudrait que je remette dans la galerie. ;-)

Figure asymptote 5de697c9857ed8c8a0f9e953b4ee7988
*** Pour masquer/découvrir le code Asymptote qui a permis de créer la figure, il faut cliquer dessus. ;-) ***

CODE ASYMPTOTE de la figure ci-dessus : Tout sélectionner
  1. import three;
  2. import geometry;
  3. unitsize(.8cm);
  4. currentprojection=obliqueX(45);
  5. real a=5, b=14, c=5;
  6. triple pA=(a,0,0), pB=(a,b,0), pC=(0,b,0), pD=(0,0,0);
  7. transform3 t=shift(0,0,c);
  8. triple pE=t*pA, pF=t*pB, pG=t*pC, pH=t*pD;
  9. transform3 t2=shift(0,0,c+1);
  10. triple pI=t2*pA, pJ=t2*pB, pK=t2*pC, pL=t2*pD;
  11. path3 facedevant=pA--pB--pF--pE--cycle,
  12. facedroite=pB--pC--pG--pF--cycle,
  13. facedessus=pH--pE--pF--pG--cycle;
  14. draw(facedevant^^facedroite^^facedessus,1bp+blue);
  15. draw(pD--pA^^pD--pC^^pD--pH,dashed+1bp+blue);
  16. draw(pE--pI^^pF--pJ^^pG--pK^^pH--pL,.8bp+.8blue);
  17. dot(pE--pI^^pF--pJ^^pG--pK^^pH--pL);
  18. distance("$14~\mathrm{m}$",project(pA),project(pB));
  19. distance("$5~\mathrm{m}$",project(pB),project(pC),rotated=false,10mm,joinpen=dashed);
  20. distance("$x$",project(pA),project(pI),rotated=false,-10mm,joinpen=dashed);
  21. distance(Label("$10~\mathrm{cm}$",align=E),project(pG),project(pK),rotated=false);


C'est une astuce, je précise ... pour une figure figée d'un dessin 3D : donc ne pas chercher à faire une sortie opengl.

Re: deferred drawing et 3D

Posté : ven. 9 avr. 2010, 23:25
par GM
Je ne réponds toujours pas à ta question de distance... mais comme ton histoire de v et de direction m'a semblé bizarre... je te montre un début d'idée qui m'a passé par la tête.

Figure asymptote 8a2308c46dbf68d0803f98c0c4e29b73
*** Pour masquer/découvrir le code Asymptote qui a permis de créer la figure, il faut cliquer dessus. ;-) ***

CODE ASYMPTOTE de la figure ci-dessus : Tout sélectionner
  1.  
  2. size(300);
  3. import three;
  4. currentprojection=perspective((8,8,6),up=Z);
  5. real a=5, b=10, c=5;
  6. triple pA=(a,0,0), pB=(a,b,0), pC=(0,b,0), pD=(0,0,0);
  7. transform3 t=shift(0,0,c);
  8. triple pE=t*pA, pF=t*pB, pG=t*pC, pH=t*pD;
  9. transform3 t2=shift(0,0,c+1);
  10. triple pI=t2*pA, pJ=t2*pB, pK=t2*pC, pL=t2*pD;
  11. path3 facedevant=pA--pB--pF--pE--cycle,
  12. facedroite=pB--pC--pG--pF--cycle,
  13. facedessus=pH--pE--pF--pG--cycle;
  14. draw(facedevant^^facedroite^^facedessus,1bp+blue);
  15. draw(pD--pA^^pD--pC^^pD--pH,dashed+1bp+blue);
  16. draw(pE--pI^^pF--pJ^^pG--pK^^pH--pL,.8bp+.8blue);
  17. dot(pE--pI^^pF--pJ^^pG--pK^^pH--pL);
  18.  
  19. void cote3D(Label L="", triple A, triple B, real k=1, bool cotepardefaut=true){
  20. triple AB=B-A,
  21. vAB=(abs(AB.x),abs(AB.y),abs(AB.z));
  22. triple v=(vAB.x>vAB.y)? ((vAB.y>vAB.z)?Z:Y) : ((vAB.x>vAB.z)?Z:X);
  23. path3 dist=(cotepardefaut)?B+k*v--A+k*v:A+k*v--B+k*v;
  24. draw(L,dist,Arrows3);
  25. draw(A--A+k*v^^B--B+k*v,dotted);
  26. }
  27. cote3D("$AB$",pA,pB,k=2,false);
  28. cote3D("$BC$",pB,pC,false);
  29. cote3D("$CD$",pC,pD);
  30. cote3D("$EF$",pE,pF);
  31. cote3D("$BE$",pB,pE,k=1.5,false);
  32. cote3D("$IL$",pI,pL,k=-1);
  33.  


Cette fois, c'est bien des flèches 3D et c'est donc visualisable avec opengl.

L'histoire de la distance... ce sera plus tard... bien plus tard pour moi, car je m'absente une semaine.

Re: deferred drawing et 3D

Posté : sam. 10 avr. 2010, 08:29
par GM
J'avais un peu de mal à faire mes valises avant de proposer un premier jet d'une proposition avec deferred drawing.

size(300,0) et u=.5

Figure asymptote e707a6cd89042aaf6cc41ae1dc89d31a
*** Pour masquer/découvrir le code Asymptote qui a permis de créer la figure, il faut cliquer dessus. ;-) ***

CODE ASYMPTOTE de la figure ci-dessus : Tout sélectionner
  1.  
  2. size(300,0);
  3. import three;
  4. currentprojection=perspective((100,60,80),up=Z);
  5.  
  6. void cote3D(picture pic=currentpicture,
  7. Label L="", triple A, triple B,
  8. bool senspardefaut=true, real k=1cm,
  9. pen p=currentpen, pen joinpen=dotted){
  10. triple A=A, B=B;
  11. path3 g=A--B;
  12. triple AB=B-A,vAB=(abs(AB.x),abs(AB.y),abs(AB.z));
  13. triple v=(vAB.x>vAB.y)? ((vAB.y>vAB.z)?Z:Y) : ((vAB.x>vAB.z)?Z:X);
  14. transform3 Tp=shift(k*v);
  15. pic.add(new void(picture f, transform3 t) {
  16. picture opic;
  17. path3 G=Tp*t*g;
  18. Label L=L.copy();
  19. draw(opic,L,G,p,Arrows3);
  20. triple Ap=t*A, Bp=t*B;
  21. draw(opic,(Ap--Tp*Ap)^^(Bp--Tp*Bp), joinpen);
  22. add(f,opic);
  23. }, true);
  24. }
  25.  
  26. real u=.5;
  27. real a=5*u, b=10*u, c=5*u;
  28. triple pA=(a,0,0), pB=(a,b,0), pC=(0,b,0), pD=(0,0,0);
  29. transform3 t=shift(0,0,c);
  30. triple pE=t*pA, pF=t*pB, pG=t*pC, pH=t*pD;
  31. transform3 t2=shift(0,0,c+1);
  32. triple pI=t2*pA, pJ=t2*pB, pK=t2*pC, pL=t2*pD;
  33. path3 facedevant=pA--pB--pF--pE--cycle,
  34. facedroite=pB--pC--pG--pF--cycle,
  35. facedessus=pH--pE--pF--pG--cycle;
  36. draw(facedevant^^facedroite^^facedessus,1bp+blue);
  37. draw(pD--pA^^pD--pC^^pD--pH,dashed+1bp+blue);
  38.  
  39. cote3D("$AB$",pB,pA,k=2cm);
  40. cote3D("$BC$",pB,pC);
  41. cote3D("$CD$",pC,pD,k=-2cm);
  42. cote3D("$EF$",pE,pF);
  43. cote3D("$BE$",pB,pE,k=1.5cm);
  44.  


size(200,0) et u=2

Figure asymptote f55fdc41de9c036949a360877939dac5
*** Pour masquer/découvrir le code Asymptote qui a permis de créer la figure, il faut cliquer dessus. ;-) ***

CODE ASYMPTOTE de la figure ci-dessus : Tout sélectionner
  1.  
  2. size(200,0);
  3. import three;
  4. currentprojection=perspective((100,60,80),up=Z);
  5.  
  6. void cote3D(picture pic=currentpicture,
  7. Label L="", triple A, triple B,
  8. bool senspardefaut=true, real k=1cm,
  9. pen p=currentpen, pen joinpen=dotted){
  10. triple A=A, B=B;
  11. path3 g=A--B;
  12. triple AB=B-A,vAB=(abs(AB.x),abs(AB.y),abs(AB.z));
  13. triple v=(vAB.x>vAB.y)? ((vAB.y>vAB.z)?Z:Y) : ((vAB.x>vAB.z)?Z:X);
  14. transform3 Tp=shift(k*v);
  15. pic.add(new void(picture f, transform3 t) {
  16. picture opic;
  17. path3 G=Tp*t*g;
  18. Label L=L.copy();
  19. draw(opic,L,G,p,Arrows3);
  20. triple Ap=t*A, Bp=t*B;
  21. draw(opic,(Ap--Tp*Ap)^^(Bp--Tp*Bp), joinpen);
  22. add(f,opic);
  23. }, true);
  24. }
  25.  
  26. real u=2;
  27. real a=5*u, b=10*u, c=5*u;
  28. triple pA=(a,0,0), pB=(a,b,0), pC=(0,b,0), pD=(0,0,0);
  29. transform3 t=shift(0,0,c);
  30. triple pE=t*pA, pF=t*pB, pG=t*pC, pH=t*pD;
  31. transform3 t2=shift(0,0,c+1);
  32. triple pI=t2*pA, pJ=t2*pB, pK=t2*pC, pL=t2*pD;
  33. path3 facedevant=pA--pB--pF--pE--cycle,
  34. facedroite=pB--pC--pG--pF--cycle,
  35. facedessus=pH--pE--pF--pG--cycle;
  36. draw(facedevant^^facedroite^^facedessus,1bp+blue);
  37. draw(pD--pA^^pD--pC^^pD--pH,dashed+1bp+blue);
  38.  
  39. cote3D("$AB$",pB,pA,k=2cm);
  40. cote3D("$BC$",pB,pC);
  41. cote3D("$CD$",pC,pD,k=-2cm);
  42. cote3D("$EF$",pE,pF);
  43. cote3D("$BE$",pB,pE,k=1.5cm);
  44.  


size(150,0) et u=4

Figure asymptote a5ddd4bc09c8e9e932b1290ede057f9f
*** Pour masquer/découvrir le code Asymptote qui a permis de créer la figure, il faut cliquer dessus. ;-) ***

CODE ASYMPTOTE de la figure ci-dessus : Tout sélectionner
  1.  
  2. size(150,0);
  3. import three;
  4. currentprojection=perspective((100,60,80),up=Z);
  5.  
  6. void cote3D(picture pic=currentpicture,
  7. Label L="", triple A, triple B,
  8. bool senspardefaut=true, real k=1cm,
  9. pen p=currentpen, pen joinpen=dotted){
  10. triple A=A, B=B;
  11. path3 g=A--B;
  12. triple AB=B-A,vAB=(abs(AB.x),abs(AB.y),abs(AB.z));
  13. triple v=(vAB.x>vAB.y)? ((vAB.y>vAB.z)?Z:Y) : ((vAB.x>vAB.z)?Z:X);
  14. transform3 Tp=shift(k*v);
  15. pic.add(new void(picture f, transform3 t) {
  16. picture opic;
  17. path3 G=Tp*t*g;
  18. Label L=L.copy();
  19. draw(opic,L,G,p,Arrows3);
  20. triple Ap=t*A, Bp=t*B;
  21. draw(opic,(Ap--Tp*Ap)^^(Bp--Tp*Bp), joinpen);
  22. add(f,opic);
  23. }, true);
  24. }
  25.  
  26. real u=4;
  27. real a=5*u, b=10*u, c=5*u;
  28. triple pA=(a,0,0), pB=(a,b,0), pC=(0,b,0), pD=(0,0,0);
  29. transform3 t=shift(0,0,c);
  30. triple pE=t*pA, pF=t*pB, pG=t*pC, pH=t*pD;
  31. transform3 t2=shift(0,0,c+1);
  32. triple pI=t2*pA, pJ=t2*pB, pK=t2*pC, pL=t2*pD;
  33. path3 facedevant=pA--pB--pF--pE--cycle,
  34. facedroite=pB--pC--pG--pF--cycle,
  35. facedessus=pH--pE--pF--pG--cycle;
  36. draw(facedevant^^facedroite^^facedessus,1bp+blue);
  37. draw(pD--pA^^pD--pC^^pD--pH,dashed+1bp+blue);
  38.  
  39. cote3D("$AB$",pB,pA,k=2cm);
  40. cote3D("$BC$",pB,pC);
  41. cote3D("$CD$",pC,pD,k=-2cm);
  42. cote3D("$EF$",pE,pF);
  43. cote3D("$BE$",pB,pE,k=1.5cm);
  44.  




Je n'ai pas le temps de vraiment tester... j'ai juste changé la valeur size et celle de u (l'unité pour définir les longueurs du pavé) et cela m'a semblé fonctionner.

NB : la façon de faire le pavé droit serait éventuellement à revoir : je rappelle que cette partie du code date de deux ans et il en en avait été question sur mathematex... et je n'y ai pas touché.

Re: deferred drawing et 3D

Posté : dim. 11 avr. 2010, 08:32
par chellier
GM a écrit :J'avais un peu de mal à faire mes valises avant de proposer un premier jet d'une proposition avec deferred drawing.

Je comprends, c'est le genre de choses auxquelles on ne peut pas s'empêcher de penser et qui peuvent gâcher des vacances ! :D

Je laisse tomber les deux premiers exemples pour m'intéresser au dernier qui répond d'avantage à ma question...
Je vois que tu as réussi à adapter la fonction distance de geometry.asy, chose que je n'avais pas réussi à faire...

Je m'explique sur ma direction v pour la flèche de cotation : je ne veux pas me contenter de la mettre dans un plan par défaut et veux pouvoir la mettre ou je veux ! Exemples : avec la fonction que tu proposes, sur la première figure, la cote du rayon est mal placée (ou alors je n'ai pas compris comment changer cela).

Image

Sur la figure suivante, à l'aide de la direction v et la fonction cote3D (code en dessous), je mets la flèche où je veux...

Image

Sinon, le deferred drawing a l'air de fonctionner, voir l'exemple suivant avec la fonction que tu as proposée (cote3D_GM en violet), et celle que j'ai adaptée (cote3D en rouge) qui me convient parfaitement (sauf peut-être le choix d'un vecteur v par défaut, je verrai plus tard...).

Code : Tout sélectionner

unitsize(1cm);
//size(7cm,0);
import solids;
settings.render=0;
settings.prc=false;
currentprojection = orthographic(5,5,2);

// v "direction" de la flèche de cotation, si cc=false le label change de côté
void cote3D(picture pic=currentpicture,
      Label L="", triple A, triple B, real d=5mm, triple v, bool cc=true,
      pen p=currentpen, pen joinpen=dotted){
   transform3 T=shift(d*unit(v));
   triple A=A, B=B;
   pic.add(new void(picture f, transform3 t) {
      picture opic;
      path3 dist;
      triple Ap=t*A, Bp=t*B;
      triple a=T*Ap, b=T*Bp;
      if (cc) {dist=a--b;}
      else {dist=b--a;}
      draw(opic,L,dist,p,Arrows3);
      draw(opic,a--Ap^^b--Bp,joinpen);
      add(f,opic);
   }, true);
}

void cote3D_GM(picture pic=currentpicture,
            Label L="", triple A, triple B,
            bool senspardefaut=true, real k=1cm,
            pen p=currentpen, pen joinpen=dotted){
  triple A=A, B=B;
  path3 g=A--B;
  triple AB=B-A,vAB=(abs(AB.x),abs(AB.y),abs(AB.z));
  triple v=(vAB.x>vAB.y)? ((vAB.y>vAB.z)?Z:Y) : ((vAB.x>vAB.z)?Z:X);
  transform3 Tp=shift(k*v);
  pic.add(new void(picture f, transform3 t) {
      picture opic;
      path3 G=Tp*t*g;
      Label L=L.copy();
      draw(opic,L,G,p,Arrows3);
      triple Ap=t*A, Bp=t*B;
      draw(opic,(Ap--Tp*Ap)^^(Bp--Tp*Bp), joinpen);
      add(f,opic);
    }, true);
}

int i;
triple A=(0,0,0), B=(0,0,5), v=(0,1,0);
draw(A--B,blue);
draw("$\vec{u}$",A--X,bp+.6*green,Arrow3);
draw("$\vec{v}$",A--Y,bp+.6*green,Arrow3);
draw("$\vec{w}$",A--Z,bp+.6*green,Arrow3);
for (i=1; i<6; ++i){
   dot((i,0,0));
   dot((0,i,0));
}
cote3D_GM("$5$",A,B,5*cm,p=purple);
cote3D("$5$",A,B,d=5*cm,v,cc=false,p=red);

shipout(bbox(1mm,invisible));


Image

Maintenant, j'ai quelques questions pour le retour des vacances ;) (ou si ça intéresse quelqu'un d'autre) :
1) À quoi sert cette ligne, je n'arrive pas bien à la comprendre ? C'est une structure conditionnelle (Si--Alors--Sinon) ?

Code : Tout sélectionner

triple v=(vAB.x>vAB.y)? ((vAB.y>vAB.z)?Z:Y) : ((vAB.x>vAB.z)?Z:X);


2) Tout se passe ici :

Code : Tout sélectionner

triple Ap=t*A, Bp=t*B;

Mais où la transformation t envoie-t-elle A et B ? (Je sais, ma question n'est pas très claire, mais j'ai vraiment rien compris ! :mrgreen: )

3) C'est pas le sujet ici, mais comment construire les pavés, je procède à peu près comme ça moi... :?

Merci, je passe le sujet en résolu, j'ai ce que je voulais 8-)

Christophe

Re: deferred drawing et 3D

Posté : dim. 11 avr. 2010, 09:03
par GM
Un dernier passage par le pc... avant de démonter le pc : les voleurs ne l'auront pas.:mrgreen:
Je laisse le serveur branché. :)

chellier a écrit :Je comprends, c'est le genre de choses auxquelles on ne peut pas s'empêcher de penser et qui peuvent gâcher des vacances ! :D

Une véritable addiction ce pc.

chellier a écrit :Je laisse tomber les deux premiers exemples pour m'intéresser au dernier qui répond d'avantage à ma question...
Je vois que tu as réussi à adapter la fonction distance de geometry.asy, chose que je n'avais pas réussi à faire...

Comme je l'ai dit : c'était un premier jet vite fait... donc je vais me repencher à nouveau sur la fonction distance de Philippe à mon retour et améliorer ma proposition.

chellier a écrit :Je m'explique sur ma direction v pour la flèche de cotation : je ne veux pas me contenter de la mettre dans un plan par défaut et veux pouvoir la mettre ou je veux ! Exemples : avec la fonction que tu proposes, sur la première figure, la cote du rayon est mal placée (ou alors je n'ai pas compris comment changer cela).

J'avais compris mais moi que je veux que dans 80% des cas, le placement soit le bon facilement sans préciser de v... donc je vais affiner mon système pour améliorer l'automatisme et essayer de faire un truc très simple pour les cas marginaux sans avoir à préciser de triple de direction : pour moi les lignes de liaisons des points d'un segment aux extrémités de la flèche de cotation peuvent être systématiquement parallèles à l'un des 3 axes de coordonnées.

chellier a écrit :Maintenant, j'ai quelques questions pour le retour des vacances ;)


Je réponds à une partie.

chellier a écrit :(ou si ça intéresse quelqu'un d'autre)


Je leur laisse le reste. :-)

chellier a écrit :À quoi sert cette ligne, je n'arrive pas bien à la comprendre ? C'est une structure conditionnelle (Si--Alors--Sinon) ?

Code : Tout sélectionner

triple v=(vAB.x>vAB.y)? ((vAB.y>vAB.z)?Z:Y) : ((vAB.x>vAB.z)?Z:X);


Oui et triple ici.
(Si cond1 Alors (Si cond2 Alors Affectation 1 Sinon Affectation 2) Sinon (Si cond3 Alors Affectation 1 Sinon Affectation 3))
Il y a probablement plus simple pour déceler la plus petite des coordonnées en valeur absolue... mais j'avais la fainéantise de chercher dans la doc d'asymptote la fonction que j'oubliais dans l'instant... donc, pour un premier jet, j'ai opté pour un truc que je savais écrire en 30 secondes.

Bon allez, je coupe...

S'il n'y a pas de connexion Internet où je vais... mon prochain message sera samedi ou dimanche prochain.