Zeichnen sich überschneidender 3D-Oberflächendiagramme

Zeichnen sich überschneidender 3D-Oberflächendiagramme

Ich versuche, sechs halbtransparente, sich überschneidende Kugeln in unterschiedlichen Farben zu zeichnen – zwei auf jeder Achse x, y, z und alle am Ursprung zusammenlaufend – wie in der Abbildung unten gezeigt. Beachten Sie, wie sich alle Kugeln überschneiden.

(Ungefähr) beabsichtigtes Ergebnis

Da diese Abbildung in erstellt wurde , habe ich versucht, die Abbildung mithilfe von in Code Matlabumzuwandeln , aber das hat nicht funktioniert. Unten sehen Sie den Code für die Abbildung.pgfplotsmatlab2tikzMatlab

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

Als nächstes habe ich versucht, die Figur in tikz-3dplotund zu zeichnen pst-solides3d. Bei beiden Methoden hatte ich das Problem, dass sich die Oberflächen nicht überschnitten. Stattdessen wurden zweidimensionale Projektionen der Kugeln separat auf der Leinwand gezeichnet, eine über der anderen, wie in den folgenden Abbildungen gezeigt. Die erste Abbildung ist die Ausgabe von tikz-3dplotund die zweite Abbildung ist die Ausgabe von pst-solides3d.

Versuch mit tikz-3dplot Versuch mit pst-solides3d

Außerdem tikz-3dplothatte ich das Problem, dass bestimmte Achsen scheinbar über den Kugeln lagen, obwohl sie eigentlich innerhalb der Kugeln liegen sollten (siehe die negative Hälfte der Y-Achse).

Nachfolgend sind die Codes für die obigen Abbildungen in der gleichen Reihenfolge aufgeführt.

\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}

Wie kann ich das gewünschte Ergebnis erzielen und dafür sorgen, dass sich die Kugeln tatsächlich schneiden, wie in der ersten Abbildung gezeigt? Kann ich meinen oben genannten Methoden etwas hinzufügen, um die Kugeln schneiden zu lassen? Wenn nicht, gibt es andere Methoden, mit denen ich das gewünschte Ergebnis erzielen kann? Die Ausgabe muss eine Vektorgrafik sein und dieselbe Schriftart wie das Hauptdokument verwenden.

Antwort1

Mit können Sie object=fusionalle Kugeln zu einem einzigen Objekt zusammenfügen. Dazu müssen Sie zusätzlich die Option setzen 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}

Bildbeschreibung hier eingeben

Antwort2

\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}

Bildbeschreibung hier eingeben

Dasselbe mit einer Lichtquelle:

\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}

Bildbeschreibung hier eingeben

Antwort3

Hier ist eine Lösung für PStricks, aber sie ist nicht sehr schön.

Thomas

\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}

Bildbeschreibung hier eingeben

Antwort4

Nachdem ich mit den hier bereitgestellten Lösungen herumgespielt hatte, beschloss ich, meine eigene, zusammengefasste Antwort zu geben. Basierend auf den vorherigen Antworten scheint das pst-solides3dPaket die beste Option zu sein. (Charles Staats schlägt vorAsymptoteals weitere mögliche Methode.) Wie Christoph anmerkt, kann man die Kugeln durchschneiden lassen object=fusion(wofür ebenfalls die solidmemoryOption erforderlich ist). Bei mir funktioniert das nur, wenn die Aktion des Fusionsobjekts auf eingestellt ist draw**(siehe die Diskussion unter Christophs Antwort).

Herberts Antwort zeigt zwei weitere Beispiele, eines mit Gitterlinien und eines mit Beleuchtung. Die Antwort von Thomas S zeigt ein ähnliches Beispiel, sowohl ohne Beleuchtung als auch ohne Gitterlinien.

Sowohl Herberts als auch Christophs Beispiele zeigen, wie der Code effizienter geschrieben werden kann.

In all diesen Beispielen werden die Achsen jedoch unterhalb der Kugeln gezeichnet, da die Achsen nicht Teil der Fusion sind. Meine Lösung hierfür besteht darin, zwei Sätze Achsen übereinander zu zeichnen. Der erste wird unterhalb der Kugeln gezeichnet und der zweite wird, wo angemessen, über die Kugeln gezeichnet.

In meinem Beispiel habe ich die Auflösung der Kugeln auf das Maximum erhöht (höhere Auflösungen scheinen zu einem Absturz des Compilers zu führen), um die Schnittpunkte so glatt wie möglich zu machen. Ich habe auch Beleuchtung hinzugefügt und die Intensität der Farben reduziert, um das Ergebnis für die Augen angenehmer zu machen.

Vielen Dank an alle für Ihre Hilfe.

Sprache bearbeiten.

\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}

Endergebnis

verwandte Informationen