答案1
也许这是朝着正确的方向发展的。
\documentclass[tikz,border=3mm]{standalone}
\begin{document}
\begin{tikzpicture}
\begin{scope}[x={(4cm,0cm)},y={({cos(30)*1.5cm},{sin(30)*1.5cm})},
z={({cos(70)*2cm},{sin(70)*2cm})},line join=round,fill opacity=0.5,thick]
\draw[fill=cyan] (0,0,0) -- (0,0,1) -- (0,1,1) -- (0,1,0) -- cycle;
\draw[fill=red] (0,0,0) -- (1,0,0) -- (1,1,0) -- (0,1,0) -- cycle;
\draw[fill=orange] (0,1,0) -- (1,1,0) -- (1,1,1) -- (0,1,1) -- cycle;
\draw[fill=cyan] (1,0,0) -- (1,0,1) -- (1,1,1) -- (1,1,0) -- cycle;
\draw[fill=red] (0,0,1) -- (1,0,1) -- (1,1,1) -- (0,1,1) -- cycle;
\draw[fill=orange] (0,0,0) -- (1,0,0) -- (1,0,1) -- (0,0,1) -- cycle;
\end{scope}
\end{tikzpicture}
\end{document}
对于更容易定制的解决方案(使用不太“简单”的代码),请考虑:
\documentclass[tikz,border=3mm]{standalone}
\tikzset{pics/parallelepiped/.style={code={
\tikzset{parallelepiped/.cd,#1}
\begin{scope}[x={(\pgfkeysvalueof{/tikz/parallelepiped/a}*1cm,0cm)},
y={({cos(\pgfkeysvalueof{/tikz/parallelepiped/theta})*\pgfkeysvalueof{/tikz/parallelepiped/b}*1cm},
{sin(\pgfkeysvalueof{/tikz/parallelepiped/theta})*\pgfkeysvalueof{/tikz/parallelepiped/b}*1cm})},
z={({cos(\pgfkeysvalueof{/tikz/parallelepiped/phi})*\pgfkeysvalueof{/tikz/parallelepiped/c}*1cm},
{sin(\pgfkeysvalueof{/tikz/parallelepiped/phi})*\pgfkeysvalueof{/tikz/parallelepiped/c}*1cm})}
,/tikz/parallelepiped/pstyle,pic actions,
declare function={mysign(\x)=ifthenelse(\x<0,-1,1);}]
\path[parallelepiped/fall,parallelepiped/fxz] (0,1,0) -- (1,1,0) -- (1,1,1) -- (0,1,1) -- cycle;
\path[parallelepiped/fall,parallelepiped/fyz,shift={({0.5-0.5*mysign(cos(\pgfkeysvalueof{/tikz/parallelepiped/phi}))},0,0)}]
(0,0,0) -- (0,0,1) -- (0,1,1) -- (0,1,0) -- cycle;
\path[parallelepiped/fall,parallelepiped/fxy,shift={(0,0,{0.5-0.5*mysign(sin(\pgfkeysvalueof{/tikz/parallelepiped/theta}))},0,0)}]
(0,0,0) -- (1,0,0) -- (1,1,0) -- (0,1,0) -- cycle;
\path[parallelepiped/fall,parallelepiped/fyz,shift={({0.5+0.5*mysign(cos(\pgfkeysvalueof{/tikz/parallelepiped/phi}))},0,0)}]
(0,0,0) -- (0,0,1) -- (0,1,1) -- (0,1,0) -- cycle;
\path[parallelepiped/fall,parallelepiped/fxy,shift={(0,0,{0.5+0.5*mysign(sin(\pgfkeysvalueof{/tikz/parallelepiped/theta}))},0,0)}]
(0,0,0) -- (1,0,0) -- (1,1,0) -- (0,1,0) -- cycle;
\path[parallelepiped/fall,parallelepiped/fxz] (0,0,0) -- (1,0,0) -- (1,0,1) -- (0,0,1) -- cycle;
\end{scope}}},parallelepiped/.cd,a/.initial=4,b/.initial=1.5,c/.initial=2,
theta/.initial=30,phi/.initial=70,pstyle/.style={draw,thick,fill opacity=0.6,
line join=round},fall/.style={draw},all
faces/.code={\tikzset{parallelepiped/fall/.style={#1}}},
fxy/.style={fill=red},xy face/.code={\tikzset{parallelepiped/fxy/.style={#1}}},
fxz/.style={fill=orange},xz face/.code={\tikzset{parallelepiped/fxz/.style={#1}}},
fyz/.style={fill=cyan},yz face/.code={\tikzset{parallelepiped/fyz/.style={#1}}}}
\begin{document}
\begin{tikzpicture}
\path (0,0) pic{parallelepiped}
(0,-4) pic{parallelepiped={a=3,phi=110,xz face={fill=yellow}}};
\end{tikzpicture}
\begin{tikzpicture}
\path (0,-4) pic{parallelepiped={a=4,phi=90,xz face={fill=yellow}}};
\end{tikzpicture}
\end{document}
据我所知,只要没有3dshapes.meta
库,拥有高度可定制的 3d 形状总是需要一些不那么简单的代码。(我正在考虑3dtools
在给定点对库的平面进行自动 3d 排序。)
编辑:修复了 90 度角度的问题,非常感谢@minhthien_2016!
答案2
您可以尝试此代码。通过更改值a, b, h, k
。
\documentclass[border=2mm,12pt,tikz]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{70}{60}
\begin{tikzpicture}[scale=1,line cap=butt,line join=round,tdplot_main_coords,declare function={a=3;b=4;h=3;k=2;
}]
\begin{scope}[canvas is xy plane at z=0]
\path
(0,0) coordinate (A)
(a,0) coordinate (B)
(a,b) coordinate (C)
(0,b) coordinate (D);
\end{scope}
\begin{scope}[canvas is xy plane at z=h]
\path
(0,k) coordinate (A')
(a,k) coordinate (B')
(a,b+k) coordinate (C')
(0,b+k) coordinate (D');
\end{scope}
\begin{scope}[opacity=0.5,thick]
\draw[fill=orange] (A) --(B) -- (C) -- (D) -- cycle;
\draw[fill=cyan] (A) --(B) -- (B') -- (A') -- cycle;
\draw[fill=red] (B) --(C) -- (C') -- (B') -- cycle;
\draw[fill=cyan] (C) --(D) -- (D') -- (C') -- cycle;
\draw[fill=yellow] (A) --(D) -- (D') -- (A') --cycle;
\draw[fill=pink] (A') --(B') -- (C') -- (D') --cycle;
\end{scope}
\end{tikzpicture}
\end{document}
非常感谢@Schrödinger's cat 的评论。我看到了使用自定义单位向量绘制 3D 轴网格修复canvas is xy plane at z=0
至canvas is yx plane at z=0
和canvas is xy plane at z=h
至canvas is yx plane at z=h
。
\documentclass[border=2mm,12pt,tikz]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{70}{60}
\begin{tikzpicture}[scale=1,line cap=butt,line join=round,tdplot_main_coords,declare function={a=3;b=4;h=3;k=-2;
}]
\begin{scope}[canvas is yx plane at z=0]
\path
(0,0) coordinate (A)
(a,0) coordinate (B)
(a,b) coordinate (C)
(0,b) coordinate (D);
\end{scope}
\begin{scope}[canvas is yx plane at z=h]
\path
(0,k) coordinate (A')
(a,k) coordinate (B')
(a,b+k) coordinate (C')
(0,b+k) coordinate (D');
\end{scope}
\begin{scope}[opacity=0.5,thick]
\draw[fill=orange] (A) --(B) -- (C) -- (D) -- cycle;
\draw[fill=cyan] (A) --(B) -- (B') -- (A') -- cycle;
\draw[fill=red] (B) --(C) -- (C') -- (B') -- cycle;
\draw[fill=cyan] (C) --(D) -- (D') -- (C') -- cycle;
\draw[fill=yellow] (A) --(D) -- (D') -- (A') --cycle;
\draw[fill=pink] (A') --(B') -- (C') -- (D') --cycle;
\end{scope}
\end{tikzpicture}
\end{document}