Asymptote 3d: Das Flackern von den Punkten eines Würfels entfernen, um zu spielen?

Asymptote 3d: Das Flackern von den Punkten eines Würfels entfernen, um zu spielen?

Meine erste Figur habe ich mit Asymptote in 3D codiert. Dabei handelt es sich um einen Spielwürfel mit Seiten, die von eins bis sechs Punkten nummeriert sind und auf klassische Weise die Zahlen 1 bis 6 darstellen. Dieser Würfel kann mit der Maus manipuliert werden.

Das Problem besteht darin, dass die Scheiben, die die Punkte darstellen, beim Manipulieren der Würfel funkeln.

Wenn ich die Draw-Anweisung (Zeile 25) kommentiere, draw(scale3(84a)*unitcube, surfacepen=white);flackern die Scheiben gar nicht, sondern die Würfel werden plötzlich transparent. Ich schließe daraus, dass das Problem daher rührt, dass die blaue Farbe der Scheiben die weiße Farbe der Flächen überdruckt. Eine Lösung wäre daher, die Flächen in zwei Schritten einzufärben, wie es mit Tikz möglich ist:

  • Flächen ohne Scheiben im Rohling
  • Einzelscheiben in blau

Aber die Befehle clip, fill, unfill, filldrawfunktionieren nicht mit der 3D- surface()Funktion.

Wie können wir die Seiten des Würfels einfärben, ohne dass es flackert?

Die Asymptote-Datei .asysieht wie folgt aus (der Code ist nicht für die Lesbarkeit optimiert):

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

Antwort1

Nach einer französischen Antwort in einem französischen Forum finden Sie hier eine ungefähre englische Antwort. Tatsächlich befinden sich die Scheiben auf/in den Flächen des Würfels, aber es ist nicht möglich, die relative Position der Scheiben in Bezug auf die Flächen zu ermitteln. Abhängig von der numerischen Näherung befinden sich die Scheiben über/unter den Flächen und numerische Artefakte erzeugen ein Flackern.

Lösung 1): jede Scheibe in die richtige Richtung verschieben, wie hier vorgeschlagen

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

Lösung 2): Erstellen Sie die reale Oberfläche der Würfelflächen. Update: Bitte finden Sie die 2. Lösung. Tatsächlich bezulatekann ein 2D-Pfad in einen 3D-Pfad umgewandelt werden. Laut Dokumentation

Patches planarer Bézier-Oberflächen werden mithilfe der Bezulate-Routine von Orest Shardt erstellt. Diese zerlegt (möglicherweise nicht einfach verbundene) Bereiche, die (gemäß der Zerowinding-Füllregel) durch einfache zyklische Pfade (die sich nur an den Endpunkten schneiden) begrenzt sind, in Unterbereiche, die durch zyklische Pfade mit einer Länge von 4 oder weniger begrenzt sind.

Um ein Loch zu erzeugen, muss man Folgendes verwenden reverse(entlang des Pfades rückwärts laufen): z. B. bezulate(unitsquate^^reverse(scale(.3)*unitcircle)). Dann surface(bezulate(unitsquate^^reverse(scale(.3)*unitcircle)))wird die Oberfläche eines Einheitsquadrats mit kleinem Loch erzeugt. Der Code für den vollständigen Würfel.

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

und das Ergebnis

Bildbeschreibung hier eingeben

OG

verwandte Informationen