使用 Tikz 在流程图中自定义形状

使用 Tikz 在流程图中自定义形状

我正在尝试使用 tikz 绘制流程图。我不是专家,特别是在使用自定义节点方面。

我看到了一些其他关于化工工艺流程图的问题,但它们很笼统,并没有解释如何自定义一个节点来获得一件设备。

这是我目前所做的,使用了我发现的一些示例:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\tikzset{HeatEx/.style={draw=black,fill=white,thick,circle,minimum width=1cm}}

\tikzset{Tank/.style={draw=black,fill=white,thick,rectangle,rounded corners=20pt,minimum width=1.5cm,minimum height=3cm,text width=1.5cm,align=center}}

\tikzset{3Phase/.style={draw=black,fill=white,thick,rectangle,rounded corners=20pt,minimum width=4cm,minimum height=1.5cm,text width=4cm,align=center}}

\tikzset{Reactor/.style={draw=black,fill=white,ultra thick,rectangle,rounded corners=20pt,minimum width=1.5cm,minimum height=4cm,text width=1.5cm,align=center}}

\def\COOLER#1#2#3{\node[HeatEx,right=#1 of #2](#3){};
     \draw[thick,-latex] (#3.south east) to[in=-20,out=160] (#3.north west);
}

\def\HEATER#1#2#3#4{\node[HeatEx,below right=#1 and #2 of #3](#4){};
     \draw[thick,-latex] (#4.north east) to[in=20,out=200] (#4.south west);
}

\def\TANK#1#2#3#4{\node[Tank,right=#1 of #2](#3){#4};}

\def\ThreeSEP#1#2#3#4{\node[3Phase,right=#1 of #2](#3){#4};}

\def\REACTOR#1#2#3#4#5{\node[Reactor,below right=#1 and #2 of #3](#4){#5};}

\begin{tikzpicture}
\node (START) {Text};

\TANK{1cm}{START}{F1}{Text}

\node[below right=of F1] (W1) {Text};

\COOLER{1cm}{F1}{C1};

\REACTOR{1cm}{1cm}{C1}{R1}{Text};

\HEATER{1cm}{1cm}{R1}{H1};

\ThreeSEP{1cm}{H1}{S1}{Text};

%Arrows    
\draw[thick,-latex] (START.east) to (F1.west);

\draw[thick,-latex] (F1.south) |- (W1);

\draw[thick,-latex] (F1.east) to (C1.west);

\draw[thick,-latex] (C1.east) -| (R1.north);

\draw[thick,-latex] (R1.south) |- (H1.west);

\draw[thick,-latex] (H1.east) to (S1.west);
\end{tikzpicture}
\end{document}

得出的结果为: 工艺流程图

我无法获得我想要的形状,主要是因为我不知道如何在节点内部绘制:

  • 热交换器内部的弯曲箭头应稍微超出圆圈;
  • 三相分离器(水平容器- \ThreeSEP)应与本图中的类似,显示四个端口:

三相分离器

我成功地在圆圈内画出了箭头(#3.south east) to (#3.north west),但如果每个节点内都有“相对参考系统”,那就(可能)更简单了。或者,至少,像这样(#3.south east+3mm,#3.south east+3mm) to (#3.north west+3mm,#3.north west+3mm)(如果它有意义的话)。

另一个问题是节点的定位,我使用多个输入来控制,但不太容易使用;如果我可以定义形状和然后它的相对位置(起初我尝试只使用\tikset{},但我无法在定义的节点内绘制)。例如,我想要第一个容器的第一个热交换器( \COOLER- C1) ,但我应该定义一个新的样式以更改 为,或者使用前者并带有负距离。above rightbelow rightabove right

最后,如果有“更聪明”的方法来做到这一点,我准备改变我的代码:-)。

谢谢大家!

答案1

相对定位(#3.south east+3mm,#3.south east+3mm) to (#3.north west+3mm,#3.north west+3mm)是存在的,但是你的语法是错误的。对于一个坐标,它应该是这样的:

($(#3.south east)+(3mm,3mm)$)`

等等。但我只使用水平移动,因为垂直移动会使箭头看起来很奇怪。

一些说明:

  • 使用\newcommand而不是\def,检查定义 TikZ 常量的首选方法是什么?;看看为什么。另外,使用newcommand 时不需要。
  • 可以\tikzset{}对所有设置进行分组,而不必每次都调用它。此外,如果您对许多节点重复相同的设置,则可以定义一个基本样式(basic在本例中),然后将其用于所有需要它的节点。这样您的 tikzset 就不会太拥挤。此外,如果需要,您可以覆盖基本样式中的任何设置(例如ultra thick您的情况)。参见代码。
  • 命令中的额外箭头\ThreeSEP现在是一个新参数,准确地说#5,是箭头顶部的坐标。如果你能更精确地说明你将如何使用它,我可以改进它。

输出

图1

代码

\documentclass[margin=10pt]{standalone}
\usepackage{tikz}

\usetikzlibrary{calc, positioning}

\tikzset{
    basic/.style={draw=black,fill=white,thick,rectangle,rounded corners=20pt, align=center},
    HeatEx/.style={draw=black,fill=white,thick,circle,minimum width=1cm},
    Tank/.style={basic, minimum width=1.5cm,minimum height=3cm,text width=1.5cm},
    3Phase/.style={basic, minimum width=4cm,minimum height=1.5cm,text width=4cm},
    Reactor/.style={basic, ultra thick,minimum width=1.5cm,minimum height=4cm,text width=1.5cm},
}

\newcommand{\COOLER}[3]{
    \node[HeatEx,right=#1 of #2](#3){};
    \draw[thick,-latex] ($(#3.south east)+(3mm,0)$) to[out=170,in=-20] ($(#3.north west)+(-3mm,0)$);
}

\newcommand{\HEATER}[4]{
    \node[HeatEx,below right=#1 and #2 of #3](#4){};
    \draw[thick,-latex] ($(#4.north east)+(3mm,0)$) to[out=200,in=20] ($(#4.south west)+(-3mm,0)$);
}

\newcommand{\TANK}[4]{
    \node[Tank,right=#1 of #2](#3){#4};
}

\newcommand{\ThreeSEP}[5]{
    \node[3Phase,right=#1 of #2](#3){#4};
    \draw[thick] (#3.south) to[out=-90,in=-90, looseness=2] node[midway] (sman) {} ($(#3.south)!.5!(#3.south east)$);
    \draw[thick,->] (sman.center) --++ (0,-1cm) -- (#5);
}

\newcommand{\REACTOR}[5]{
    \node[Reactor,below right=#1 and #2 of #3](#4){#5};
}

\begin{document}
\begin{tikzpicture}
    \node (START) {Text};
    \TANK{1cm}{START}{F1}{Text}
    \node[below right=of F1] (W1) {Text};
    \COOLER{1cm}{F1}{C1}
    \REACTOR{1cm}{1cm}{C1}{R1}{Text}
    \HEATER{1cm}{1cm}{R1}{H1}
    \ThreeSEP{1cm}{H1}{S1}{Hello}{15,-12}

%Arrows    
    \draw[thick,-latex] (START.east) to (F1.west);
    \draw[thick,-latex] (F1.south) |- (W1);
    \draw[thick,-latex] (F1.east) to (C1.west);
    \draw[thick,-latex] (C1.east) -| (R1.north);
    \draw[thick,-latex] (R1.south) |- (H1.west);
    \draw[thick,-latex] (H1.east) to (S1.west);
\end{tikzpicture}
\end{document}

答案2

您可以通过引入一个不可见的外圆并在其外面画一条曲线来获得更好版本的冷却器和加热器:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\tikzset{HeatEx/.style={draw=black,fill=white,thick,circle,minimum width=1cm}}

\def\COOLER#1#2#3{\node[HeatEx,right=#1 of #2](#3){};
     \node (dummy) [circle, minimum width=1.4cm] at (#3.center) {};
     \draw[thick,-latex] (dummy.south east) to[in=-20,out=160] (dummy.north west);
}

\begin{tikzpicture}        
\node (START) {Start};
\COOLER{1cm}{START}{C1};
\draw[->, thick] (START) -- (C1.west);
\end{tikzpicture}      

\end{document}

其结果为: 带假圈的冷却器

dummy您将需要根据箭头伸出圆圈的距离来调整圆圈的大小。

相关内容