deep-learning - 使用 TikZ 制作堆叠的 3D 块
问题描述
我已经开始学习 TikZ 来制作图形,但是我仍然局限于非常简单的绘图(线条、文本等)。几乎我需要构建的所有图形都会像 3D 矩形块一样相互跟随,有时会在上面写字或像此图像中的箭头:,(我取自https://arxiv.org/abs/1707.02921)
它读起来真的很好。我想知道是否有模块化的积木可以绘制这种图形?或者,如果一个人需要事先非常胜任 TikZ 并且没有捷径可用。(如果防守得当,我对 TikZ 以外的其他选择持开放态度)
编辑:正如我所说,我正在寻找 TikZ 中的模块化块和示例语法来创建堆叠的 3D 块,这不是一个完美的代码,可以准确地构建附图(尽管它会令人难以置信)。
解决方案
对于我所有的“3D tikz 绘图”,我一直在使用这个 tikz 示例中的平行六面体形状。从中,您可以构建任何颜色、大小等的基本 3D 形状。
我对您的示例的初步工作(这是我在 overleaf.com 上使用的确切代码)和相应的图像如下。仍然需要做很多工作才能达到完全相同的结果(中间块上方的箭头、加号、两侧的不同颜色、文本字体等)。
\documentclass[tikz]{standalone}
%% Language and font encodings
\usepackage[english]{babel}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\definecolor{darkblue}{HTML}{1f4e79}
\definecolor{lightblue}{HTML}{00b0f0}
\definecolor{salmon}{HTML}{ff9c6b}
\usetikzlibrary{backgrounds,calc,shadings,shapes.arrows,arrows,shapes.symbols,shadows,positioning,decorations.markings,backgrounds,arrows.meta}
% Define parallelepiped shape:
\makeatletter
\pgfkeys{/pgf/.cd,
parallelepiped offset x/.initial=2mm,
parallelepiped offset y/.initial=2mm
}
\pgfdeclareshape{parallelepiped}
{
\inheritsavedanchors[from=rectangle] % this is nearly a rectangle
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{north west}
\inheritanchor[from=rectangle]{north east}
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
\inheritanchor[from=rectangle]{mid}
\inheritanchor[from=rectangle]{mid west}
\inheritanchor[from=rectangle]{mid east}
\inheritanchor[from=rectangle]{base}
\inheritanchor[from=rectangle]{base west}
\inheritanchor[from=rectangle]{base east}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{south west}
\inheritanchor[from=rectangle]{south east}
\backgroundpath{
% store lower right in xa/ya and upper right in xb/yb
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/parallelepiped
offset x}}
\pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/parallelepiped
offset y}}
\def\ppd@offset{\pgfpoint{\pgfutil@tempdima}{\pgfutil@tempdimb}}
\pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
\pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
\pgfpathclose
\pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@ya}}{\ppd@offset}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@yb}}{\ppd@offset}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xa}{\pgf@yb}}{\ppd@offset}}
\pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
\pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@yb}}{\ppd@offset}}
}
}
\makeatother
\tikzset{
% Dark blue blocks
block/.style={
parallelepiped,fill=white, draw,
minimum width=0.8cm,
minimum height=2.4cm,
parallelepiped offset x=0.5cm,
parallelepiped offset y=0.5cm,
path picture={
\draw[top color=darkblue,bottom color=darkblue]
(path picture bounding box.south west) rectangle
(path picture bounding box.north east);
},
text=white,
},
% Orange-ish blocks
conv/.style={
parallelepiped,fill=white, draw,
minimum width=0.8cm,
minimum height=2.4cm,
parallelepiped offset x=0.5cm,
parallelepiped offset y=0.5cm,
path picture={
\draw[top color=salmon,bottom color=salmon]
(path picture bounding box.south west) rectangle
(path picture bounding box.north east);
},
text=white,
},
% Taller Light blue blocks:
plate/.style={
parallelepiped,fill=white, draw,
minimum width=0.1cm,
minimum height=7.4cm,
parallelepiped offset x=0.5cm,
parallelepiped offset y=0.5cm,
path picture={
\draw[top color=lightblue,bottom color=lightblue]
(path picture bounding box.south west) rectangle
(path picture bounding box.north east);
},
text=white,
},
% Arrows between blocks:
link/.style={
color=lightblue,
line width=2mm,
},
}
\begin{document}
\begin{tikzpicture}
% The order of blocks matters since some are partially hidden behind subsequent blocks.
\node[conv](conv1){\rotatebox{90}{Conv}};
\node[plate,right=0.2cm of conv1](plate1){};
% yshift to align the bottom of that blocks with the previous taller block.
\node[block,right=0.2cm of plate1,yshift=-2.5cm](resblock1){\rotatebox{90}{ResBlock}};
\node[block,above=0.1cm of resblock1](resblock2){\rotatebox{90}{ResBlock}};
\node[block,above=0.1cm of resblock2](resblock3){\rotatebox{90}{ResBlock}};
\node[block,right=0.2cm of resblock1](x1){\rotatebox{90}{(X4)}};
\node[block,above=0.1cm of x1](x2){\rotatebox{90}{(X3)}};
\node[block,above=0.1cm of x2](x3){\rotatebox{90}{(X2)}};
\node[plate,right=0.2cm of x2](plate2){};
\node[block,right=0.6cm of x2](resblock4){\rotatebox{90}{ResBlock4}};
\node[block,right=2cm of resblock4](resblock5){\rotatebox{90}{ResBlock5}};
\node[conv,right=0.2cm of resblock5](conv2){\rotatebox{90}{Conv}};
\draw [-,link] ([xshift=0.2cm,yshift=0.2cm]resblock4.east) -- ([yshift=0.2cm]resblock5.west);
\draw [-triangle 60,link] ([xshift=0.2cm,yshift=0.2cm]conv2.east) -- ([xshift=1.5cm,yshift=0.2cm]conv2.east);
\end{tikzpicture}
\end{document}
推荐阅读
- r - 将列名转换为新列的行值并将其值填充到另一个新列
- database - 如何从 IntelliJ 运行 QuestDB?
- arrays - 从集合转换为数组时类型不匹配
- sonos - CustomSD 服务无法播放曲目
- php - Mysql子查询laravel 8.0
- python - Python中的过滤函数(简单问题)
- ubuntu - 有人可以告诉我如何在 lubuntu 上将 python 添加到我的路径环境变量中吗?
- reactjs - 仅使用来自另一个集合的 id 填充数据
- jquery - 幻灯片自动的问题:它对齐奇怪的元素
- python - 在python的未读邮件中从特定人那里获取附件