繪製相交的 3D 曲面圖

繪製相交的 3D 曲面圖

我試圖繪製六個不同顏色的半透明相交球體——每個軸 x、y、z 上有兩個球體,所有球體都在原點連接——如下圖所示。注意所有球體如何相交。

(粗略地)預期的結果

鑑於該圖是在 中創建的Matlab,我嘗試使用 將圖轉換為pgfplots程式碼matlab2tikz,但這不起作用。下面是Matlab該圖的程式碼。

Theta=linspace(0,2*pi,200);
Phi=linspace(-pi/2,pi/2,200);
[theta,phi]=meshgrid(Theta,Phi);

rho1=cos(theta).*cos(phi);
rho2=-cos(theta).*cos(phi);
rho3=sin(theta).*cos(phi);
rho4=-sin(theta).*cos(phi);
rho5=sin(phi);
rho6=-sin(phi);

[x1,y1,z1]=sph2cart(theta,phi,rho1);
[x2,y2,z2]=sph2cart(theta,phi,rho2);
[x3,y3,z3]=sph2cart(theta,phi,rho3);
[x4,y4,z4]=sph2cart(theta,phi,rho4);
[x5,y5,z5]=sph2cart(theta,phi,rho5);
[x6,y6,z6]=sph2cart(theta,phi,rho6);

surf(x1,y1,z1,'FaceColor','red','EdgeColor','none')
hold on
surf(x2,y2,z2,'FaceColor','red','EdgeColor','none')
surf(x3,y3,z3,'FaceColor','blue','EdgeColor','none')
surf(x4,y4,z4,'FaceColor','blue','EdgeColor','none')
surf(x5,y5,z5,'FaceColor','green','EdgeColor','none')
surf(x6,y6,z6,'FaceColor','green','EdgeColor','none')

alpha(0.6)
camlight left
lighting flat

tikz-3dplot接下來我嘗試在和中繪製圖形pst-solides3d。使用這兩種方法時,我遇到了曲面不相交的問題。相反,球體的二維投影是在畫布上單獨繪製的,一個在另一個之上,如下圖所示。第一個圖是 的輸出tikz-3dplot,第二個圖是 的輸出pst-solides3d

嘗試使用 tikz-3dplot 嘗試使用 pst-solides3d

對於tikz-3dplot,我還遇到了一個問題,某些軸似乎位於球體頂部,而實際上它們應該出現在球體內部(參考 y 軸的負半部)。

下面是上述圖的程式碼,順序相同。

\documentclass[11pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz,tikz-3dplot}
    \usetikzlibrary{arrows}

\begin{document}

\tdplotsetmaincoords{70}{135}

\begin{tikzpicture}[tdplot_main_coords,fill  opacity=.5,>=latex]
\pgfsetlinewidth{.1pt}

\tdplotsphericalsurfaceplot{72}{36}{4*abs(cos(\tdplotphi)*sin(\tdplottheta))}{black!85!white}{blue}
{\draw[color=black,thick,->]  (-6,0,0) --  (6,0,0)  node[anchor=north  east]{\textbf{x}};}
{\draw[color=black,thick,->]  (0,-6,0) --  (0,6,0)  node[anchor=north  west]{\textbf{y}};}
{\draw[color=black,thick,->]  (0,0,-6) --  (0,0,6)  node[anchor=south]{\textbf{z}};}

\tdplotsphericalsurfaceplot{72}{36}{4*abs(cos(\tdplottheta))}{black!85!white}{green}
{\draw[color=black,ultra thin,->]  (-6,0,0) --  (6,0,0)  node[anchor=north  east]{};}
{\draw[color=black,ultra thin,->]  (0,-6,0) --  (0,6,0)  node[anchor=north  west]{};}
{\draw[color=black,ultra thin,->]  (0,0,-6) --  (0,0,6)  node[anchor=south]{};}

\tdplotsphericalsurfaceplot{72}{36}{4*abs(sin(\tdplotphi)*sin(\tdplottheta))}{black!85!white}{red}
{\draw[color=black,ultra thin,->]  (-6,0,0) --  (6,0,0)  node[anchor=north  east]{};}
{\draw[color=black,ultra thin,->]  (0,-6,0) --  (0,6,0)  node[anchor=north  west]{};}
{\draw[color=black,ultra thin,->]  (0,0,-6) --  (0,0,6)  node[anchor=south]{};}

\end{tikzpicture}

\end{document}

\documentclass[11pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{pstricks,pst-solides3d}

\begin{document}

\begin{pspicture}(-6,-6)(6,6)

\psset{viewpoint=100  100  100,Decran=150}
\axesIIID[showOrigin=true,mathLabel=false,axisemph=\textbf,labelsep=8pt](-7,-7,-7)(7,7,7)
\psSolid[object=sphere,r=2,action=draw*,fillcolor=green,linecolor=black!85!white,linewidth=0.5pt,opacity=0.6,ngrid=15 24,name=green2](0,0,-2)
\psSolid[object=sphere,r=2,action=draw*,fillcolor=blue,linecolor=black!85!white,linewidth=0.5pt,opacity=0.6,ngrid=15 24,name=blue2](-2,0,0)
\psSolid[object=sphere,r=2,action=draw*,fillcolor=red,linecolor=black!85!white,linewidth=0.5pt,opacity=0.6,ngrid=15 24,name=red2](0,-2,0)
\psSolid[object=sphere,r=2,action=draw*,fillcolor=green,linecolor=black!85!white,linewidth=0.5pt,opacity=0.6,ngrid=15 24,name=green1](0,0,2)
\psSolid[object=sphere,r=2,action=draw*,fillcolor=red,linecolor=black!85!white,linewidth=0.5pt,opacity=0.6,ngrid=15 24,name=red1](0,2,0)
\psSolid[object=sphere,r=2,action=draw*,fillcolor=blue,linecolor=black!85!white,linewidth=0.5pt,opacity=0.6,ngrid=15 24,name=blue1](2,0,0)

\end{pspicture}

\end{document}

如何才能獲得預期的結果並使球體真正相交,如第一張圖所示?我可以在上面的方法中添加什麼來使球體相交嗎?如果沒有,我可以使用其他方法來獲得預期的結果嗎?輸出必須是向量圖形,並使用與主文檔相同的字體。

答案1

您可以使用object=fusion將所有球體合併為一個物件。為此,您還必須設定選項solidmemory

\documentclass[11pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{pstricks,pst-solides3d}

\begin{document}

\begin{pspicture}(-6,-6)(6,6)

\psset{viewpoint=100  100  100,Decran=150}
\axesIIID[showOrigin=true,mathLabel=false,axisemph=\textbf,labelsep=8pt](-7,-7,-7)(7,7,7)
\psset{linecolor=black!85!white,linewidth=0.5pt, opacity=0.6, strokeopacity=0.6,
       object=sphere, r=2, ngrid=15 24, action=none, solidmemory, grid}
\psSolid[fillcolor=green, name=green2](0,0,-2)
\psSolid[fillcolor=blue, name=blue2](-2,0,0)
\psSolid[fillcolor=red, name=red2](0,-2,0)
\psSolid[fillcolor=green, name=green1](0,0,2)
\psSolid[fillcolor=red, name=red1](0,2,0)
\psSolid[fillcolor=blue, name=blue1](2,0,0)

\psSolid[object=fusion, base=green1 green2 red1 red2 blue1 blue2, action=draw**]

\end{pspicture}

\end{document}

在此輸入影像描述

答案2

\documentclass[pstricks]{standalone}
\usepackage{pst-solides3d}
\begin{document}

\begin{pspicture}(-6,-6)(6,6)
\psset{viewpoint=100 100 100,Decran=150,solidmemory,object=sphere,r=2,
   action=none,linewidth=0.5pt,ngrid=45 60,linecolor=black!85!white}
\axesIIID[mathLabel=false,axisemph=\textbf,labelsep=8pt](-7,-7,-7)(7,7,7)
\psSolid[fillcolor=green,name=green2](0,0,-2)
\psSolid[fillcolor=blue,name=blue2](-2,0,0)
\psSolid[fillcolor=red,name=red2](0,-2,0)
\psSolid[fillcolor=green,name=green1](0,0,2)
\psSolid[fillcolor=red,name=red1](0,2,0)
\psSolid[fillcolor=blue,name=blue1](2,0,0)
\psSolid[object=fusion,base=green2 blue2 red2 green1 red1 blue1,action=draw**,opacity=0.9]
\end{pspicture}

\end{document}

在此輸入影像描述

與光源相同:

\documentclass[pstricks]{standalone}
\usepackage{pst-solides3d}
\begin{document}

\begin{pspicture}(-6,-6)(6,6)
\psset{viewpoint=60 45 30 rtp2xyz,lightsrc=viewpoint,
  Decran=60,solidmemory,object=sphere,r=2,
  action=none,linewidth=0.5pt,
  ngrid=45 60,linecolor=black!45!white}
\axesIIID[axisemph=\mathbf,labelsep=8pt](-5,-5,-5)(5,5,5)
\psSolid[fillcolor=green,name=green2](0,0,-2)
\psSolid[fillcolor=blue,name=blue2](-2,0,0)
\psSolid[fillcolor=red,name=red2](0,-2,0)
\psSolid[fillcolor=green,name=green1](0,0,2)
\psSolid[fillcolor=red,name=red1](0,2,0)
\psSolid[fillcolor=blue,name=blue1](2,0,0)
\psSolid[object=fusion,base=green2 blue2 red2 green1 red1 blue1,action=draw**,opacity=0.7,grid]
\end{pspicture}

\end{document}

在此輸入影像描述

答案3

這是 pstricks 的一個解決方案,但不是很好。

湯瑪斯

\documentclass[11pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{pstricks,pst-solides3d}

\begin{document}

\begin{pspicture}(-6,-6)(6,6)

\psset{viewpoint=100 100 100,Decran=150,solidmemory}
\axesIIID[showOrigin=true,mathLabel=false,axisemph=\textbf,labelsep=8pt](-7,-7,-7)(7,7,7)

\psSolid[object=sphere,r=2,action=draw*,fillcolor=green,linecolor=black!85!white,linewidth=0.5pt,ngrid=45 60,name=green2,action=none](0,0,-2)
\psSolid[object=sphere,r=2,action=draw*,fillcolor=blue,linecolor=black!85!white,linewidth=0.5pt,ngrid=45 60,name=blue2,action=none](-2,0,0)
\psSolid[object=sphere,r=2,action=draw*,fillcolor=red,linecolor=black!85!white,linewidth=0.5pt,ngrid=45 60,name=red2,action=none](0,-2,0)
\psSolid[object=sphere,r=2,action=draw*,fillcolor=green,linecolor=black!85!white,linewidth=0.5pt,ngrid=45 60,name=green1,action=none](0,0,2)
\psSolid[object=sphere,r=2,action=draw*,fillcolor=red,linecolor=black!85!white,linewidth=0.5pt,ngrid=45 60,name=red1,action=none](0,2,0)
\psSolid[object=sphere,r=2,action=draw*,fillcolor=blue,linecolor=black!85!white,linewidth=0.5pt,ngrid=45 60,name=blue1,action=none](2,0,0)

\psSolid[object=fusion,base=green2 blue2 red2 green1 red1 blue1,action=draw**,opacity=0.7,linewidth=0.01pt,grid]
\end{pspicture}

\end{document}

在此輸入影像描述

答案4

在修改了這裡提供的解決方案後,我決定給出我自己的總結答案。根據之前的答案,看來pst-solides3d套餐是最好的選擇。 (查爾斯·斯塔茨建議漸近線作為另一種可能的方法。 )正如克里斯托夫所指出的,可以使球體相交object=fusion(這也需要該solidmemory選項)。對我來說,這僅在融合物件的動作設定為時才有效draw**(請參閱克里斯托夫的回答下面的討論)。

赫伯特的答案顯示了另外兩個示例,一個帶有網格線,另一個帶有照明。 Thomas S 的回答顯示了一個類似的例子,既沒有照明,也沒有網格線。

Herbert 和 Christoph 的範例都展示如何更有效地編寫程式碼。

然而,在所有這些範例中,軸都繪製在球體下方,因為軸不是融合的一部分。我的解決方案是在彼此之上繪製兩組軸。第一個繪製在球體下方,第二個繪製在適當的球體頂部。

在我的範例中,我將球體的分辨率提高到最大(更高的解析度似乎會導致編譯器崩潰),以使相交盡可能平滑。我還添加了照明並降低了顏色的強度,以使結果更容易被眼睛看到。

感謝大家的幫忙。

編輯:語言。

\documentclass[11pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{pstricks,pst-solides3d}

\begin{document}

\begin{pspicture}(-6,-6)(6,6)

\psset{lightsrc=100 50 130,viewpoint=100 100 100,Decran=150}
\axesIIID[showOrigin=true,axisnames={}](-6.5,-6.5,-6.5)(6.5,6.5,6.5)

\psset{linewidth=0.5pt,opacity=0.7,object=sphere,r=2,ngrid=39 90,action=none,solidmemory,grid}

\psSolid[fillcolor=green!70!gray,name=green2](0,0,-2)
\psSolid[fillcolor=blue!70!gray,name=blue2](-2,0,0)
\psSolid[fillcolor=red!70!gray,name=red2](0,-2,0)
\psSolid[fillcolor=green!70!gray,name=green1](0,0,2)
\psSolid[fillcolor=red!70!gray,name=red1](0,2,0)
\psSolid[fillcolor=blue!70!gray,name=blue1](2,0,0)

\psSolid[object=fusion,base=green1 green2 red1 red2 blue1 blue2,action=draw**]

\psset{linewidth=0.8pt,opacity=1}
\axesIIID[showOrigin=false,mathLabel=false,axisemph=\textbf,labelsep=8pt](4,4,4)(6.5,6.5,6.5)

\end{pspicture}

\end{document}

最後結果

相關內容