我希望重现图像
我希望改进我的最小示例和针对其他情况的想法:
MWE:
\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[tdplot_main_coords,font=\sffamily]
\draw (0,-3,0) -- (0,3,0);
\draw (2,0,-3) -- (-2,0,3);
\draw[fill=red,opacity=0.3] (-3,0,-3) -- (-3,0,3) -- (3,0,3) -- (3,0,-3) -- cycle;
\draw (-3,0,-3) -- (-3,0,3) -- (3,0,3) -- (3,0,-3) -- cycle;
\draw[fill=blue,opacity=0.2] (-3,-3,0) -- (-3,3,0) -- (3,3,0) -- (3,-3,0) -- cycle;
\draw (-3,-3,0) -- (-3,3,0) -- (3,3,0) -- (3,-3,0) -- cycle;
\draw[fill=green,opacity=0.1] (2,-3,-3) -- (2,3,-3) -- (-2,3,3) -- (-2,-3,3) -- cycle;
\draw (2,-3,-3) -- (2,3,-3) -- (-2,3,3) -- (-2,-3,3) -- cycle;
\draw[fill=red,opacity=0.1] (-3,0,-3) -- (-3,0,3) -- (3,0,3)
-- (3,0,-3) -- cycle;
\draw[thick](-3,0,0)--(3,0,0);
\draw[thick](-3,0,0)--(3,0,0);
\fill[red] (0,0,0) circle (3pt);
\node[anchor=south west,align=center] (line) at (4,6,3.5)
{Solution\\ intersection};
\draw[-latex] (line) to[out=180,in=75] (0.05,0.05,0.1);
\end{tikzpicture}
\end{document}
输出:
我希望大家能够开心地回答这个问题。
\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[tdplot_main_coords,font=\sffamily]
\draw (0,-3,0) -- (0,3,0);
\draw (2,0,-3) -- (-2,0,3);
\draw[fill=red,opacity=0.3] (-3,0,-3) -- (-3,0,3) -- (3,0,3) -- (3,0,-3) --
cycle;
\draw (-3,0,-3) -- (-3,0,3) -- (3,0,3) -- (3,0,-3) -- cycle;
\draw[fill=blue,opacity=0.2] (-3,-3,0) -- (-3,3,0) -- (3,3,0) -- (3,-3,0) --
cycle;
\draw (-3,-3,0) -- (-3,3,0) -- (3,3,0) -- (3,-3,0) -- cycle;
\draw[fill=green,opacity=0.1] (2,-3,-3) -- (2,3,-3) -- (-2,3,3) -- (-2,-3,3)
-- cycle;
\draw (2,-3,-3) -- (2,3,-3) -- (-2,3,3) -- (-2,-3,3) -- cycle;
\draw[fill=red,opacity=0.1] (-3,0,-3) -- (-3,0,3) -- (3,0,3) -- (3,0,-3) --
cycle;
\draw[thick](-3,0,0)--(3,0,0);
\draw[thick](-3,0,0)--(3,0,0);
\fill[red] (0,0,0) circle (3pt);
\node[anchor=south west,align=center] (line) at (4,6,3.5) {Solution\\
intersection};
\draw[-latex] (line) to[out=180,in=75] (0.05,0.05,0.1);
\end{tikzpicture}
\end{document}
输出:
答案1
更新:由于这是一个重复的问题,我试图改进这一点。到目前为止,人们必须手动对绘图元素进行排序。这种类型的示例可以在本答案的下半部分找到。人们可能想知道是否有可能让 Ti钾Z 决定以什么顺序绘制事物。答案是肯定的。这可以被认为是原理证明。
- 绘制顺序取决于物体的距离。该距离可以定义为物体重心在屏幕法线上的投影。
- 为了计算这些预测,我们需要一些工具。我在这里使用的工具来自实验图书馆
3dtools
,可以找到这里。您需要将库另存为,tikzlibrary3dtools.code.tex
并将其放在 TeX 可以找到的地方,例如与下面文档相同的文件夹。 - 给定投影,我们可以建立一个顺序并在相应的层中绘制内容。
此时,您仍然需要手动找出交集部分。正如我所说,这是一个原理证明。pgfplots 提供了非常类似的功能patchplots
。
\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3dtools}
\begin{document}
% define a command for the projections (to become a part of the library)
\newcommand\GetProj[2]{\begingroup
\foreach \Coord [count=\nCoord] in #1
{\ifnum\nCoord=1
\xdef\temp{\Coord}
\else
\xdef\temp{\temp+\Coord}
\fi}
\edef\ntemp{\noexpand\path[overlay,3d coordinate={(tmp)=\temp}];}
\ntemp
\pgfmathsetmacro{#2}{TD("(n)o(tmp)")}
\pgfmathsmuggle#2\endgroup}
% counter for 3d ordering
\newcounter{tdorder}
% set a sufficient number of layers (for more complex scenarios you need more)
\foreach \X in {1,...,20}
{\pgfdeclarelayer{layer\X}
\ifnum\X=1
\xdef\LstLayers{layer\X}
\else
\xdef\LstLayers{\LstLayers,layer\X}
\fi}
\pgfsetlayers\LstLayers
\tikzset{closed polygon/.style={insert path={foreach \Coord [count=\nCoord] in {#1}
{\ifnum\nCoord=1
\Coord
\else
-- \Coord
\fi} -- cycle}},polygon/.style={insert path={foreach \Coord [count=\nCoord] in {#1}
{\ifnum\nCoord=1
\Coord
\else
-- \Coord
\fi}}}}
% main code
\foreach \X in {5,15,...,355}
{\tdplotsetmaincoords{90+30*sin(\X)}{\X}
\begin{tikzpicture}[tdplot_main_coords,font=\sffamily,fill opacity=1]
\path[tdplot_screen_coords,use as bounding box] (-5,-5) rectangle (5,5);
% define the vertices (there are certainly superior naming conventions)
\path (-3,-3,0) coordinate (m1) (-3,0,-3) coordinate (m2)
(-3,0,0) coordinate (m3) (-3,0,3) coordinate (m4) (-3,3,0) coordinate (m5)
(-2,-3,3) coordinate (m6) (-2,0,3) coordinate (m7) (-2,3,3) coordinate (m8)
(0,-3,0) coordinate (m9) (0,0,0) coordinate (O) (0,3,0) coordinate (p1)
(2,-3,-3) coordinate (p2) (2,0,-3) coordinate (p3) (2,3,-3) coordinate (p4)
(3,-3,0) coordinate (p5) (3,0,-3) coordinate (p6) (3,0,0) coordinate (p7)
(3,0,3) coordinate (p8) (3,3,0) coordinate (p9);
% define the plane data as a list of <drawing options>/<shape>/<vertices>
\def\PlaneData{%
{draw,fill=red}/closed polygon/{(m2),(p3),(O),(m3)},%
{draw,fill=red}/closed polygon/{(p6),(p3),(O),(p7)},%
{draw,fill=red}/closed polygon/{(m4),(m7),(O),(m3)},%
{draw,fill=red}/closed polygon/{(p8),(m7),(O),(p7)},%
{draw,fill=blue}/closed polygon/{(m1),(m3),(O),(m9)},%
{draw,fill=blue}/closed polygon/{(m5),(m3),(O),(p1)},%
{draw,fill=blue}/closed polygon/{(p5),(p7),(O),(m9)},%
{draw,fill=blue}/closed polygon/{(p9),(p7),(O),(p1)},%
{draw,fill=green}/closed polygon/{(m6),(m9),(O),(m7)},%
{draw,fill=green}/closed polygon/{(m8),(p1),(O),(m7)},%
{draw,fill=green}/closed polygon/{(p2),(m9),(O),(p3)},%
{draw,fill=green}/closed polygon/{(p4),(p1),(O),(p3)},%
{draw,thick}/polygon/{(m3),(O)},%
{draw,thick}/polygon/{(O),(p7)}}
% normal of screen (last row of the rotation matrix)
\path[overlay] ({sin(\tdplotmaintheta)*sin(\tdplotmainphi)},
{-1*sin(\tdplotmaintheta)*cos(\tdplotmainphi)},
{cos(\tdplotmaintheta)}) coordinate (n);
% build up the list of projections
\foreach \Style/\Poly/\CoordLst [count=\nC] in \PlaneData
{%
\GetProj{\CoordLst}{\currproj}
\ifnum\nC=1
\xdef\LstProj{\currproj}
\else
\xdef\LstProj{\LstProj,\currproj}
\fi}
% draw the planes in appropriate layers
\foreach \Style/\Poly/\CoordLst [count=\nC] in \PlaneData
{%
\GetProj{\CoordLst}{\currproj}
\setcounter{tdorder}{1}
\foreach \Proj in \LstProj
{\pgfmathtruncatemacro{\itest}{ifthenelse(\Proj<\currproj,1,0)}
\ifnum\itest=1
\stepcounter{tdorder}
\fi}
\begin{pgfonlayer}{layer\number\value{tdorder}}
\edef\temp{\noexpand\path[\Style,\Poly={\CoordLst}];}
\temp
\end{pgfonlayer}
}
%
\end{tikzpicture}}
\end{document}
不用说,这可以应用于与 D 膜相交的其他场景。
\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3dtools}
\begin{document}
\newcommand\GetProj[2]{\begingroup
\foreach \Coord [count=\nCoord] in #1
{\ifnum\nCoord=1
\xdef\temp{\Coord}
\else
\xdef\temp{\temp+\Coord}
\fi}
\edef\ntemp{\noexpand\path[overlay,3d coordinate={(tmp)=\temp}];}
\ntemp
\pgfmathsetmacro{#2}{TD("(n)o(tmp)")}
\pgfmathsmuggle#2\endgroup}
\newcounter{tdorder}
\foreach \X in {1,...,20}
{\pgfdeclarelayer{layer\X}
\ifnum\X=1
\xdef\LstLayers{layer\X}
\else
\xdef\LstLayers{\LstLayers,layer\X}
\fi}
\pgfsetlayers\LstLayers
\tikzset{closed polygon/.style={insert path={foreach \Coord [count=\nCoord] in {#1}
{\ifnum\nCoord=1
\Coord
\else
-- \Coord
\fi} -- cycle}},polygon/.style={insert path={foreach \Coord [count=\nCoord] in {#1}
{\ifnum\nCoord=1
\Coord
\else
-- \Coord
\fi}}}}
%
\foreach \X in {5,15,...,355}
{\tdplotsetmaincoords{90-30*cos(\X)}{\X}
\begin{tikzpicture}[tdplot_main_coords,font=\sffamily,fill opacity=1]
\path[tdplot_screen_coords,use as bounding box] (-5,-5) rectangle (5,5);
\path foreach \X [count=\cX] in {A,B}
{foreach \Y [count=\cY] in {A,B}
{foreach \Z [count=\cZ] in {A,B}
{(4.5-3*\cX,4.5-3*\cY,4.5-3*\cZ) coordinate(\X\Y\Z)}}}
(0,0,4.5) coordinate (T);
\def\PlaneData{%
{draw,fill=red}/closed polygon/{(AAA),(ABA),(ABB),(AAB)},%
{draw,fill=red!80}/closed polygon/{(ABA),(BBA),(BBB),(ABB)},%
{draw,fill=red!50}/closed polygon/{(BBA),(BAA),(BAB),(BBB)},%
{draw,fill=red!70}/closed polygon/{(BAA),(AAA),(AAB),(BAB)},%
{draw,fill=blue}/closed polygon/{(AAA),(ABA),(T)},%
{draw,fill=blue!80}/closed polygon/{(ABA),(BBA),(T)},%
{draw,fill=blue!50}/closed polygon/{(BBA),(BAA),(T)},%
{draw,fill=blue!70}/closed polygon/{(BAA),(AAA),(T)},%
{draw,fill=gray}/closed polygon/{(AAB),(ABB),(BBB),(BAB)},%
{draw,thick}/polygon/{(AAA),(AAB)}}
% normal of screen
\path[overlay] ({sin(\tdplotmaintheta)*sin(\tdplotmainphi)},
{-1*sin(\tdplotmaintheta)*cos(\tdplotmainphi)},
{cos(\tdplotmaintheta)}) coordinate (n);
% build up the list of projections
\foreach \Style/\Poly/\CoordLst [count=\nC] in \PlaneData
{%
\GetProj{\CoordLst}{\currproj}
\ifnum\nC=1
\xdef\LstProj{\currproj}
\else
\xdef\LstProj{\LstProj,\currproj}
\fi}
% draw the planes in appropriate layers
\foreach \Style/\Poly/\CoordLst [count=\nC] in \PlaneData
{%
\GetProj{\CoordLst}{\currproj}
\setcounter{tdorder}{1}
\foreach \Proj in \LstProj
{\pgfmathtruncatemacro{\itest}{ifthenelse(\Proj<\currproj,1,0)}
\ifnum\itest=1
\stepcounter{tdorder}
\fi}
\begin{pgfonlayer}{layer\number\value{tdorder}}
\edef\temp{\noexpand\path[\Style,\Poly={\CoordLst}];}
\temp
\end{pgfonlayer}
}
%
\end{tikzpicture}}
\end{document}
旧答案:您需要按正确的顺序绘制飞机的各个部分。对于您案例中给定的视图,这是
\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{70}{110}
\foreach \X in {0.1,0.2,...,1,0.9,0.8,...,0.2}
{\begin{tikzpicture}[tdplot_main_coords,font=\sffamily,fill opacity=\X]
\draw[fill=red] (-3,0,-3) -- (2,0,-3) -- (0,0,0) -- (-3,0,0) -- cycle;
\draw[thick](-3,0,0) -- (0,0,0);
\draw[fill=blue] (-3,-3,0) -- (-3,3,0) -- (0,3,0) -- (0,-3,0) -- cycle;
\draw[fill=red] (-3,0,0) -- (0,0,0) -- (-2,0,3) -- (-3,0,3) -- cycle;
\draw[fill=green] (2,-3,-3) -- (2,3,-3) -- (-2,3,3) -- (-2,-3,3) -- cycle;
\draw[fill=red] (3,0,-3) -- (2,0,-3) -- (0,0,0) -- (3,0,0) -- cycle;
\draw[fill=blue] (3,-3,0) -- (3,3,0) -- (0,3,0) -- (0,-3,0) -- cycle;% %\draw (0,-3,0) -- (0,3,0);
\draw[fill=red] (3,0,0) -- (0,0,0) -- (-2,0,3) -- (3,0,3) -- cycle;
\draw[thick](0,0,0)--(3,0,0);
\fill[red] (0,0,0) circle (3pt);
\node[anchor=south west,align=center] (line) at (4,6,3.5)
{Solution\\ intersection};
\draw[-latex] (line) to[out=180,in=75] (0.05,0.05,0.1);
\end{tikzpicture}}
\end{document}
您需要fill opacity
从循环中选择您最喜欢的。
这里是使相交平面完全可旋转的另一种方法。
您“仅”需要区分足够多的情况。
附录:至于您在评论中提出的要求:该策略与上述完全相同。
\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{70}{110}
\foreach \X in {0.1,0.2,...,1,0.9,0.8,...,0.2}
{\begin{tikzpicture}[tdplot_main_coords,font=\sffamily,fill opacity=\X]
\draw[fill=red] (-3,0,-3) -- (-3,0,0) -- (3,0,0) -- (3,0,-3) -- cycle;
\draw[fill=green] (-3,2,-3) -- (-3,0,0) -- (3,0,0) -- (3,2,-3) -- cycle;
\draw[fill=blue] (-3,-3,0) -- (-3,3,0) -- (3,3,0) -- (3,-3,0) -- cycle;
\draw[fill=green] (-3,-2,3) -- (-3,0,0) -- (3,0,0) -- (3,-2,3) -- cycle;
\draw[fill=red] (-3,0,3) -- (-3,0,0) -- (3,0,0) -- (3,0,3) -- cycle;
\draw[thick](-3,0,0)--(3,0,0);
\fill[red] (0,0,0) circle (3pt);
\node[anchor=south west,align=center,text opacity=1] (line) at (4,6,3.5) {Solution\\
intersection};
\draw[-latex] (line) to[out=180,in=75] (0.05,0.05,0.1);
\end{tikzpicture}}
\end{document}
答案2
恕我直言,pstricks 也提供了一个优雅的解决方案。
\documentclass{article}
\usepackage[dvipsnames]{xcolor}
\definecolor{LightCyan}{rgb}{0.88,1,1}
\definecolor{LightRed}{rgb}{1,0.8,0.7961}
\definecolor{LightGreen}{rgb}{0.8235,0.9137,0.6863}
\usepackage{pst-solides3d}
\pagestyle{empty}
\begin{document}
\begin{pspicture}(-1.5,-1.5)(1.5,1.5)%
\psset{solidmemory,unit=.75cm,algebraic,viewpoint=40 30 20}%
\defFunction{planeAi}(u,v){u}{v}{0}%
\psSolid[object=surfaceparametree,base=-2 2 -2 2,fillcolor=LightCyan,function=planeAi,ngrid=50,action=none,name=A1,opacity=.4](0,0,0)%
\defFunction{planeAii}(u,v){u}{v}{-2*v}%
\psSolid[object=surfaceparametree,base=-2 2 2 5 sqrt div neg 2 5 sqrt div,fillcolor=LightGreen,function=planeAii,ngrid=50,action=none,name=A2,opacity=.5](0,0,0)%
\defFunction{planeAiii}(u,v){2*u}{v}{-3*u}%
\psSolid[object=surfaceparametree,base=4 3 div 5 sqrt div neg 4 3 div 5 sqrt div -2 2,fillcolor=LightRed,function=planeAiii,ngrid=50,action=none,name=A3,opacity=.5](0,0,0)%
\psSolid[object=fusion,base=A1 A2 A3,grid,action=draw**,opacity=.5](0,0,0)%
\composeSolid%
\psPoint(0,0,0){O}\psdot(O)%
\end{pspicture}%
%
\hspace{1cm}
%
\begin{pspicture}(-1.5,-1.5)(1.5,1.5)%
\psset{solidmemory,unit=.75cm,algebraic,viewpoint=40 30 20}%
\defFunction{planeAi}(u,v){u}{v}{0}%
\psSolid[object=surfaceparametree,base=-2 2 -2 2,fillcolor=LightCyan,function=planeAi,ngrid=50,action=none,name=A1](0,0,0)%
\defFunction{planeAii}(u,v){u}{v}{-2*v}%
\psSolid[object=surfaceparametree,base=-2 2 -0.84 0.84,fillcolor=LightGreen,function=planeAii,ngrid=50,action=none,name=A2](0,0,0)%
\defFunction{planeAiii}(u,v){u}{2*v}{3*v}%
\psSolid[object=surfaceparametree,base=-2 2 0.56 -0.56 ,fillcolor=LightRed,function=planeAiii,ngrid=50,action=none,name=A3](0,0,0)%
\psSolid[object=fusion,base=A1 A2 A3,linecolor=gray,grid,action=draw**,opacity=.5](0,0,0)%
\composeSolid%
\psPoint(-2,0,0){P}\psPoint(2,0,0){Q}\psline[linewidth=.8pt](P)(Q)%
\end{pspicture}%
\end{document}