Asymptote 3d:消除骰子點上的閃爍來玩?

Asymptote 3d:消除骰子點上的閃爍來玩?

我用 3d 中的 Asymptote 編寫了我的第一個圖形,這是一個骰子,用經典的方式用一到六個點編號的面來玩,代表數字 1 到 6。這個骰子可以用滑鼠操作。

問題是當你操縱骰子時,代表點的圓盤會閃閃發光。

當我評論繪製語句(第 25 行)時,draw(scale3(84a)*unitcube, surfacepen=white);圓盤根本不閃爍,但骰子突然變得透明。我的結論是,問題出在光碟的藍色疊印在白色的表面上。因此,解決方案是分兩步驟為臉部著色,就像使用 Tikz 一樣:

  • 沒有空白光碟的面
  • 藍色單碟

clipfillunfillfilldraw指令不適用於 3dsurface()功能。

我們如何在不閃爍的情況下為骰子的表面著色?

Asymptote 檔案.asy如下(程式碼未進行優化以使其可讀):

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

答案1

在法語論壇上得到法語答案後,請找出近似的英語答案。事實上,圓盤位於立方體的表面上/內部,但不可能知道圓盤相對於表面的相對位置。根據數值近似,圓盤位於面的上方/下方,且數值偽影會產生閃爍。

解決方案1):將每個盤朝正確的方向移動,這是這裡提出的

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

解決方案2):創建骰子麵的真實表面。更新:請找到第二個解決方案。確實bezulate可以將 2D 路徑轉換為 3D。根據文件,

平面貝塞爾曲面片是使用Orest Shardt 的bezulate 例程構建的,該例程將由簡單循環路徑(僅在端點相交)界定的(可能是非簡單連接的)區域(根據零纏繞填充規則)分解為由長度為4 的循環路徑界定的子區域或較少的。

要建立洞,必須使用reverse(沿著路徑向後運行):例如bezulate(unitsquate^^reverse(scale(.3)*unitcircle))。然後surface(bezulate(unitsquate^^reverse(scale(.3)*unitcircle)))建立一個有小孔的單位正方形的表面。完整骰子的程式碼。

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

和結果

在此輸入影像描述

奧格

相關內容