J'ai codé ma première figure avec Asymptote en 3D. Il s'agit d'un dé à jouer avec des faces numérotées par un à six points représentant les nombres 1 à 6 de façon classique. Ce dé est manipulable avec la souris.

Lorsqu'on manipule le dé, les disques représentant les points scintillent en créant des artefacts indésirables, ce qui pose problème.

Lorsque je commente l'instruction draw(scale3(84a)*unitcube, surfacepen=white); qui colorie les faces du cube en blanc, les disques ne scintillent plus du tout et le dé devient transparent.

J'en conclus donc que le problème vient de la surimpression de la couleur bleue des disques sur la couleur blanche des faces. Une solution serait alors de colorier les faces en deux étapes comme on peut le faire avec Tikz :

  • les faces sans les disques en blanc
  • les disques seuls en bleu

Malheureusement les commandes clip, fill, filldraw fonctionnent uniquement en 2D et pas en 3D.

Comment peut-on colorier les faces du dé sans avoir de scintillement ?

Le fichier Asymptote, d'extension .asy est le suivant, (le code n'est pas optimisé de façon à être lisible) :

Ouvrir dans l'éditeur Overleaf
import three;
currentprojection =orthographic((5,2,3));
currentlight=nolight; 
settings.tex="latex"; // Moteur LaTeX utilisé pour la compilation (latex, pdflatex, ...)
settings.outformat="pdf"; // Format de sortie ; eps par défaut
settings.prc=true; // Format PRC de la figure ; vrai par défaut
settings.render=-1; // Rendu des figures ; -1 par défaut
size(6cm,0);
real a = 0.05;
// definition des faces du dé en 2D comme un patron
path    carre = box ((0,0),(84a,84a)),
    disque = scale(9a)*unitcircle,
    patron1[] = shift(42a,42a)*disque,
    patron2[] = shift(14a,70a)*disque^^shift(70a,14a)*disque,
    patron3[] = shift(14a,70a)*disque^^shift(70a,14a)*disque^^shift(42a,42a)*disque, 
    patron4[] = shift(14a,14a)*disque^^shift(14a,70a)*disque^^shift(70a,14a)*disque
^^shift(70a,70a)*disque,
    patron5[] = shift(14a,14a)*disque^^shift(14a,70a)*disque^^shift(70a,14a)*disque
^^shift(70a,70a)*disque^^shift(42a,42a)*disque,   
    patron6[] = shift(14a,14a)*disque^^shift(14a,70a)*disque^^shift(70a,14a)*disque
^^shift(70a,70a)*disque^^shift(42a,70a)*disque^^shift(42a,14a)*disque;

transform3 tX=shift(84a*X), tY=shift(84a*Y), tZ=shift(84a*Z);       
path3   facegauche[] =path3(patron6,ZXplane),
    facedroite[] =path3(patron1,ZXplane),
    faceavant[] =path3(patron2,YZplane),
    facearriere[] =path3(patron5,YZplane),  
    facehaut[] =path3(patron4,XYplane),     
    facebas[] =path3(patron3,XYplane);      
draw(scale3(84a)*unitcube, surfacepen=white);
draw(box(O, 84a*(X+Y+Z)), gray);
draw(surface(facegauche),blue);
draw(surface(tY*facedroite),blue);
draw(surface(tZ*facehaut),blue);
draw(surface(facebas),blue);
draw(surface(facearriere),blue);
draw(surface(tX*faceavant),blue);

Posée 10 Jul '17, 11:46

Andr%C3%A9C's gravatar image

AndréC
61121124
Taux d'acceptation : 25%

Modifiée 14 Aoû '17, 12:18

Pathe's gravatar image

Pathe ♦♦
7.5k42203251

1

La question vient d'être résolue en français sur le forum mathematex et en anglais sur tex.stackexchange

(10 Jul '17, 17:01) AndréC Andr%C3%A9C's gravatar image

Pourriez-vous indiquer la solution ici pour ne pas générer des questions sans réponse apparente ?

(10 Jul '17, 17:46) pluton pluton's gravatar image

Je veux bien mais comme ce ne sont pas mes réponses, je vais demander d'abord à leurs auteurs de bien vouloir répondre ici (car il y a deux solutions).

(10 Jul '17, 17:49) AndréC Andr%C3%A9C's gravatar image

Trois solutions ont été données sur le forum mathematex dédié à Asymptote par les modérateurs OG et rebouxo. Ils m'autorisent tous deux à les reproduire ici même.

Première solution de OG : C'est normal (réponse facile). En effet les disques sont exactement sur la surface des faces, aucun des objets n'est positionné au dessus/au dessous...

Solution 1 : décaler de $\varepsilon=0.001$ chaque disque dans le bon sens.

Voici le code :

Ouvrir dans l'éditeur Overleaf
import three;
    currentprojection =orthographic((5,2,3));
    currentlight=nolight;
    settings.tex="latex"; // Moteur LaTeX utilisé pour la compilation (latex, pdflatex, ...)
    settings.outformat="pdf"; // Format de sortie ; eps par défaut
    settings.prc=true; // Format PRC de la figure ; vrai par défaut
    settings.render=-1; // Rendu des figures ; -1 par défaut
    size(6cm,0);
    real a = 0.05;
    path    carre = box ((0,0),(84a,84a)),
          disque = scale(9a)*unitcircle,
          patron1[] = shift(42a,42a)*disque,
          patron2[] = shift(14a,70a)*disque^^shift(70a,14a)*disque,
          patron3[] = shift(14a,70a)*disque^^shift(70a,14a)*disque^^shift(42a,42a)*disque,
          patron4[] = shift(14a,14a)*disque^^shift(14a,70a)*disque^^shift(70a,14a)*disque^^shift(70a,70a)*disque,
          patron5[] = shift(14a,14a)*disque^^shift(14a,70a)*disque^^shift(70a,14a)*disque^^shift(70a,70a)*disque^^shift(42a,42a)*disque,
          patron6[] = shift(14a,14a)*disque^^shift(14a,70a)*disque^^shift(70a,14a)*disque^^shift(70a,70a)*disque^^shift(42a,70a)*disque^^shift(42a,14a)*disque;
    transform3 tX=shift((84a+.001)*X), tY=shift((84a+.001)*Y), tZ=shift((84a+.001)*Z);      
    path3    facegauche[] =shift(0,-0.001,0)*path3(patron6,ZXplane),
          facedroite[] =path3(patron1,ZXplane),
          faceavant[] =path3(patron2,YZplane),
          facearriere[] =shift(-0.001,0,0)*path3(patron5,YZplane),   
          facehaut[] =path3(patron4,XYplane),      
          facebas[] =shift(0,0,-0.001)*path3(patron3,XYplane);      
    draw(scale3(84a)*unitcube, surfacepen=white);
    draw(box(O, 84a*(X+Y+Z)), gray);
    draw(surface(facegauche),blue);
    draw(surface(tY*facedroite),blue);
    draw(surface(tZ*facehaut),blue);
    draw(surface(facebas),blue);
    draw(surface(facearriere),blue);
    draw(surface(tX*faceavant),blue);

Deuxième solution par rebouxo : La source des scintillements vient que tu as des objets plans l'un sur l'autre. Il suffit de décaler les cercles légèrement du cube pour que le scintillement disparaisse, j'ai décalé de h.

Je propose ceci comme code :

Ouvrir dans l'éditeur Overleaf
import three;
currentprojection =orthographic((5,2,3));
currentlight=nolight;
settings.tex="latex"; // Moteur LaTeX utilisé pour la compilation (latex, pdflatex, ...)
settings.outformat="pdf"; // Format de sortie ; eps par défaut
settings.prc=true; // Format PRC de la figure ; vrai par défaut
settings.render=-1; // Rendu des figures ; -1 par défaut
size(6cm,0);
real a = 0.05;
real h = 0.001 ;
surface cube = scale3(84*a)*unitcube ;

surface disqueX = scale3(9*a)*unitdisk ;
surface disqueY = rotate(90,Y)*scale3(9*a)*unitdisk ;
surface disqueZ = rotate(90,X)*scale3(9*a)*unitdisk ;

draw(cube, white, gray+linewidth(1bp));

surface[] face1 = {shift(42*a,42*a,84*(a+h))*disqueX} ;
surface[] face6 = {shift(14*a,14*a,-h)*disqueX,
         shift(14*a,42*a,-h)*disqueX,
         shift(14*a,70*a,-h)*disqueX,
         shift(70*a,14*a,-h)*disqueX,
         shift(70*a,42*a,-h)*disqueX,
         shift(70*a,70*a,-h)*disqueX} ;

surface[] face2 = {shift(-h,14*a,14*a)*disqueY,
         shift(-h,70*a,70*a)*disqueY} ;

surface[] face5 = {shift(84*(a+h),14*a,14*a)*disqueY,
         shift(84*(a+h),14*a,70*a)*disqueY,
         shift(84*(a+h),42*a,42*a)*disqueY,
         shift(84*(a+h),70*a,14*a)*disqueY,
         shift(84*(a+h),70*a,70*a)*disqueY} ;

surface[] face4 = {shift(14*a,84*(a+h),14*a)*disqueZ,
         shift(14*a,84*(a+h),70*a)*disqueZ,
         shift(70*a,84*(a+h),14*a)*disqueZ,
         shift(70*a,84*(a+h),70*a)*disqueZ} ;

surface[] face3 = {shift(14*a,-h,14*a)*disqueZ,
         shift(42*a,-h,42*a)*disqueZ,
         shift(70*a,-h,70*a)*disqueZ} ;

surface[][] points = {face1,face2,face3,face4,face5,face6} ;

for(int i = 0 ; i < 6 ; ++i)
  {
    for(int cpt = 0 ; cpt <= i ; ++cpt)
      {
   draw(points[i][cpt],blue,blue) ;
      }
  }

La principale différence est d'utiliser systématiquement les objets 3d, plutôt que de gérer des objets plans, pour les plaquer sur le dés. Plutôt une histoire de goût, mais je soupçonne que ta méthode soit plus efficace, si il y a beaucoup d'objets. Comme je ne peux pas concaténer des surface (dommage) j'ai fait des tableaux de surface (un pour chaque face) et un tableau de ces tableaux, pour éviter des copier-coller.

Il manque des choses dans asymptote : faire des trous, des chanfreins, bref toutes choses utile pour la CAO.

Troisième solution par OG (moins facile) : dessiner réellement chaque face comme le carré privé des disques :

Asymptote peut transformer un contour 2D en une surface 3D. C'est ce qui est fait pour les étiquettes en 3D : bezulate est ton ami. @rebouxo: il y a aussi extrude qui peut servir..

Il faut donc construire chaque face trouée et là plus besoin du décalage de $\varepsilon$ Pour que bezulate comprenne la construction 1 carré privé d'un disque, il faut faire un reverse(disque), c'est la règle.

Voici le code :

Ouvrir dans l'éditeur Overleaf
currentprojection =orthographic((5,2,3));
    currentlight=nolight;
    settings.tex="latex"; // Moteur LaTeX utilisé pour la compilation (latex, pdflatex, ...)
    settings.outformat="pdf"; // Format de sortie ; eps par défaut
    settings.prc=true; // Format PRC de la figure ; vrai par défaut
    settings.render=-1; // Rendu des figures ; -1 par défaut
    size(6cm,0);
    real a = 0.05;
    path    carre = box ((0,0),(84a,84a)),
          // reverse est capital pour créer les trous avec bezulate
          // c'est la règle : unitsquare et disque ne seront pas dans le
          // même sens, donc bezulate comprend que c'est un trou
          disque = scale(9a)*reverse(unitcircle),

          patron1[] = shift(42a,42a)*disque,
          patron2[] = shift(14a,70a)*disque^^shift(70a,14a)*disque,
          patron3[] = shift(14a,70a)*disque^^shift(70a,14a)*disque^^shift(42a,42a)*disque,
          patron4[] = shift(14a,14a)*disque^^shift(14a,70a)*disque^^shift(70a,14a)*disque^^shift(70a,70a)*disque,
          patron5[] = shift(14a,14a)*disque^^shift(14a,70a)*disque^^shift(70a,14a)*disque^^shift(70a,70a)*disque^^shift(42a,42a)*disque,
          patron6[]=  shift(14a,14a)*disque^^shift(14a,70a)*disque^^shift(70a,14a)*disque^^shift(70a,70a)*disque^^shift(42a,70a)*disque^^shift(42a,14a)*disque;
    transform3 tX=shift((84a)*X), tY=shift((84a)*Y), tZ=shift((84a)*Z);      
    path3    facegauche[] =path3(patron6,ZXplane),
          facedroite[] =path3(patron1,ZXplane),
          faceavant[] =path3(patron2,YZplane),
          facearriere[] =path3(patron5,YZplane),   
          facehaut[] =path3(patron4,XYplane),      
          facebas[] =path3(patron3,XYplane);

 //   draw(scale3(84a)*unitcube, surfacepen=white);
    draw(box(O, 84a*(X+Y+Z)), gray);
    draw(surface(facegauche),blue);
    draw(surface(tY*facedroite),blue);
    draw(surface(tZ*facehaut),blue);
    draw(surface(facebas),blue);
    draw(surface(facearriere),blue);
    draw(surface(tX*faceavant),blue);
// les faces trouées
    path[] gp6=bezulate(scale(84a)*unitsquare^^patron6);
    path[] gp5=bezulate(scale(84a)*unitsquare^^patron5);
    path[] gp4=bezulate(scale(84a)*unitsquare^^patron4);
    path[] gp3=bezulate(scale(84a)*unitsquare^^patron3);
    path[] gp2=bezulate(scale(84a)*unitsquare^^patron2);
    path[] gp1=bezulate(scale(84a)*unitsquare^^patron1);
    surface s1=shift((0,84a,84a))*rotate(90,Y)*rotate(90,X)*surface(gp1);
    surface s2=shift(84a,0,0)*rotate(-90,Y)*surface(gp2);
    surface s3=surface(gp3);
    surface s4=shift((0,0,84a))*surface(gp4);
    surface s5=shift((0,0,84a))*rotate(90,Y)*surface(gp5);
    surface s6=shift((0,0,84a))*rotate(90,Y)*rotate(90,X)*surface(gp6);
    draw(s6,red);
    draw(s5,red);
    draw(s4,red);
    draw(s3,red);
    draw(s2,red);
    draw(s1,red);

alt text

Lien permanent

Publiée 11 Jul '17, 02:10

Andr%C3%A9C's gravatar image

AndréC
61121124
Taux d'acceptation : 25%

Modifiée 11 Jul '17, 10:53

Votre réponse
(dés)activer l'aperçu

Suivre cette question

Par courriel :

Une fois que vous serez enregistré, vous pourrez souscrire à n'importe quelle mise à jour ici

Par flux RSS :

Réponses

Réponses et commentaires

Bases de Markdown

  • *italique* ou _italique_
  • **gras** ou __gras__
  • Lien ::[texte](http://url.com/ "Titre ")
  • Image : ?![alt texte](/path/img.jpg "Titre ")
  • Liste numérotée : 1. Foo 2. Bar
  • Pour ajouter un passage à la ligne, ajoutez deux espaces à l'endroit où vous souhaitez que la ligne commence.
  • Les balises HTML de base sont également prises en charge.