Assíntota 3d: Remover a cintilação dos pontos de um dado para jogar?

Assíntota 3d: Remover a cintilação dos pontos de um dado para jogar?

Codifiquei minha primeira figura com Assíntota em 3d que é um dado para jogar com faces numeradas de um a seis pontos representando os números de 1 a 6 de forma clássica. Estes dados podem ser manipulados com o mouse.

O problema é que os discos que representam os pontos brilham quando você manipula os dados.

Quando comento a declaração de sorteio (linha 25), draw(scale3(84a)*unitcube, surfacepen=white);os discos não piscam, mas de repente os dados ficam transparentes. Concluo que o problema vem do fato da cor azul dos discos estar sobreposta à cor branca das faces. Uma solução seria, portanto, colorir os rostos em duas etapas, como pode ser feito com o Tikz:

  • Rostos sem discos em branco
  • Discos individuais em azul

Mas os comandos clip, fill, unfill, filldrawnão funcionam com a surface()função 3d.

Como podemos colorir as faces dos dados sem piscar?

O arquivo Asymptote .asyé o seguinte (o código não está otimizado para ser legível):

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*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);

Responder1

Depois de uma resposta em francês em um fórum francês, encontre uma resposta aproximada em inglês. Na verdade os discos estão nas faces do cubo mas não é possível saber qual a posição relativa dos discos em relação às faces. Dependendo da aproximação numérica, os discos ficam acima/abaixo das faces e artefatos numéricos criam cintilação.

Solução 1): desloque cada disco na direção certa, o que é proposto aqui

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+00.1)*X), tY=shift((84a+.001)*Y), tZ=shift((84a+0.01)*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);

Solução 2): crie a superfície real das faces dos dados. Atualização: encontre a segunda solução. Na verdade, bezulatepode transformar o caminho 2D em 3D. De acordo com a documentação,

Patches de superfícies planas de Bezier são construídos usando a rotina bezulate de Orest Shardt, que decompõe regiões (possivelmente conectadas de forma não simples) limitadas (de acordo com a regra de preenchimento de enrolamento zero) por caminhos cíclicos simples (que se cruzam apenas nos pontos finais) em sub-regiões limitadas por caminhos cíclicos de comprimento 4 ou menos.

Para criar furo é necessário usar reverse(correr para trás ao longo do caminho): por exemplo bezulate(unitsquate^^reverse(scale(.3)*unitcircle)). Em seguida, surface(bezulate(unitsquate^^reverse(scale(.3)*unitcircle)))cria a superfície de um quadrado unitário com pequeno furo. O código para os dados completos.

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)),
      // 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);

e o resultado

insira a descrição da imagem aqui

OG

informação relacionada