我正在尝试使用创建我的钻机的流程图LaTex
,但我无法弄清楚如何在图中两条独立线的交点处创建半圆形跳跃。我当前的代码和输出如下。
\documentclass[11pt]{standalone}
\usepackage{lmodern}
\renewcommand*{\familydefault}{\sfdefault}
\usepackage{sfmath}
\usepackage[version=4]{mhchem}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,fit,positioning,intersections,shapes.geometric,
decorations,patterns,decorations.markings}
\tikzset{
every path/.style={thick},
every node/.style={
font={\normalsize},
align=center,
transform shape
},
}
\begin{document}
\begin{tikzpicture}[node distance=0.75cm]
\tikzset{
sv/.pic={
\def \x {0.43}
\node[draw,isosceles triangle,fill=none] (a) at (-\x,0) {};
\node[draw,isosceles triangle,shape border rotate=180,fill=none] at (\x,0){};
\draw[fill=none] (0,0) circle (0.22);
},%shutoff valve
lifwv/.pic={
\def \x {1pt}
\node[draw,circle,minimum size=0.6cm] (a) at (0,0){};
\node[circle,minimum size=0.4cm] (b) at (0.1,0){};
\fill (b.90) circle (\x) (b.0) circle (\x) (b.180) circle (\x) (b.270) circle (\x);
\draw[->] (a.90) -- ++(0,0.5) -- ++(0.5,0) node[right,ellipse,draw,inner sep=0.5pt](mv){M.V.};
\draw[->] (a.270) -- ++(0,-0.5) -- node[pos=0.5,nosep] (evap){} ++(1,0) -- ++(0,0.815) -- (a.0);
\node[below right = of evap,draw,yshift=0.25cm] (syp){Pump};
\draw[->] (syp) -|(evap);
},%liquid injection right 4-way valve
pt/.pic={
\draw (0,0) -- ++(0.25,0) node[right,draw,circle,minimum size=0.5cm,font=\small,inner sep=0pt](a){P};
},%pressure transducer
jump/.pic={
\filldraw[draw=black,fill=white] (0.15,0) arc (0:180:0.15);
\draw[red,dashed] (0,0) circle (0.5);
},
mfc/.style={
draw,minimum width=1.75cm,minimum height=0.9cm,
text height=1.5ex
},
nosep/.style={
inner sep=0pt,
outer sep=0pt,
},%meeting-point
}
\node[mfc] (mfc1) {a};
\node[below = of mfc1,mfc] (mfc2) {\ce{b}};
\node[below = of mfc2,mfc] (mfc3) {\ce{c}};
\node[below = of mfc3,mfc] (mfc4) {\ce{d}};
\node[below = of mfc4,mfc] (mfc5) {\ce{e}};
\node[below = of mfc5,mfc] (mfc6) {\ce{f}};
\foreach \y in {1,2,...,6}{
\draw[->] (mfc\y.east) --++(0.5,0) node[right=12pt] (svmfcc\y){} node[right=24pt](svmfcr\y){};
\pic at (svmfcc\y){sv};
};
%line-1
\draw[->] (svmfcr1) -- node[pos=0.45,nosep](mpl1){} ++(1.5,0) -- pic[pos=0.4,-]{pt}++(0,0.75) -- ++(2,0) pic[right]{lifwv} node[right](l1){};
\foreach \y in {3,5,6} {
\draw[->] (svmfcr\y) -- ++(0.75,0);
};
\draw[->] (svmfcr6) ++(0.75,0) -- (mpl1);
%line-2
\draw[->] (svmfcr2) -- node[pos=0.75,nosep] (mpl2){} ++(1.5,0) -- pic[-,pos=0.4]{pt}++(0,-0.75) -- ++(2,0) pic[right]{lifwv} node[right](l2){};
\draw[->] (svmfcr4) -- ++(1.16,0) -- (mpl2);
\draw[->] (svmfcr4) -- pic[pos=0.6,-]{jump} ++(1.16,0) -- (mpl2);
\end{tikzpicture}
\end{document}
我知道一种方法是定义一个半圆形的图,用白色填充,然后将其覆盖在交叉点处(如当前代码中实现的,用红色虚线圆圈突出显示)。但理想情况下,我想实现一个没有填充的跳跃,并将其定义为线上的标记装饰,就像可以使用decorations.markings
库定义的箭头装饰一样。有办法实现这个吗?
答案1
第一部分是原始答案,在底部可以找到更灵活的实现。
以下是使用自定义的另一种方法to path
。添加\usetikzlibrary{calc}
,并定义jump
为
jump/.style={
to path={
let \p1=(\tikztostart),\p2=(\tikztotarget),\n1={atan2(\y2-\y1,\x2-\x1)} in
(\tikztostart) -- ($($(\tikztostart)!#1!(\tikztotarget)$)!0.15cm!(\tikztostart)$)
arc[start angle=\n1+180,end angle=\n1,radius=0.15cm] -- (\tikztotarget)}
},
jump/.default={0.5}
将其用作
\draw (a) to[jump] (b);
样式的可选参数定义了凸起沿线发生的位置,默认值是中间位置。最小示例:
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{
jump/.style={
to path={
let \p1=(\tikztostart),\p2=(\tikztotarget),\n1={atan2(\y2-\y1,\x2-\x1)} in
(\tikztostart) -- ($($(\tikztostart)!#1!(\tikztotarget)$)!0.15cm!(\tikztostart)$)
arc[start angle=\n1+180,end angle=\n1,radius=0.15cm] -- (\tikztotarget)}
},
jump/.default={0.5}
}
\begin{document}
\begin{tikzpicture}
\fill [blue!10] (-0.5,-0.5) rectangle (2.5,1.5);
\draw (0,1) to[jump] ++(0,-1) to[jump=0.2] ++(2,0) to[jump=0.7] ++(-1,1);
\end{tikzpicture}
\end{document}
由此产生了如下结果:
可能不是立即就能看出来发生了什么,因此可能需要进行一些解释:
我建议阅读第 14.13 节路径操作to
在 TikZ 手册(针对版本 3.0.1a)中,如果您对路径一无所知。
键to path
用于在两点之间创建自定义路径。在该上下文中,宏\tikztostart
和\tikztotarget
正如预期的那样表示起点和终点。因此,在 中\draw (a) to (b);
,\tikztostart
是a
,而\tikztotarget
是b
。
开始部分let
用于计算开始和结束之间的角度,保存在 中\n1
。此语法在 14.15 节中描述Let 操作在手册中。
接下来的几行定义了绘制的线本身,结构是(a) -- (b) arc[...] -- (c)
。
第二个坐标使用以下语法定义calc
,如第 13.5 节所述坐标计算在手册中:
($($(\tikztostart)!#1!(\tikztotarget)$)!0.15cm!(\tikztostart)$)
这是一个嵌套的坐标计算。#1
表示样式的参数,默认值为0.5
。因此默认情况下($(\tikztostart)!#1!(\tikztotarget)$)
是起点和终点中间的坐标。语法表示距离 0.15 厘米、朝向 的($(a)!0.15cm!(b)$)
点。因此,完整计算的总体效果是获取距离中间点 0.15 厘米、朝向起点的坐标。a
b
从该点开始,使用计算出的角度绘制圆弧,并以 0.15 厘米作为半径:
arc[start angle=\n1+180,end angle=\n1,radius=0.15cm]
并画出最后一条直线来完成-- (\tikztotarget);
。
在您的(不是那么最小的)示例中实现:
\documentclass[11pt]{standalone}
\usepackage{lmodern}
\renewcommand*{\familydefault}{\sfdefault}
\usepackage{sfmath}
\usepackage[version=4]{mhchem}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,fit,positioning,intersections,shapes.geometric,
decorations,patterns,decorations.markings,
calc % <-- added
}
\tikzset{
every path/.style={thick},
every node/.style={
font={\normalsize},
align=center,
transform shape
},
}
\begin{document}
\begin{tikzpicture}[
node distance=0.75cm,
sv/.pic={
\def \x {0.43}
\node[draw,isosceles triangle,fill=none] (a) at (-\x,0) {};
\node[draw,isosceles triangle,shape border rotate=180,fill=none] at (\x,0){};
\draw[fill=none] (0,0) circle (0.22);
},%shutoff valve
lifwv/.pic={
\def \x {1pt}
\node[draw,circle,minimum size=0.6cm] (a) at (0,0){};
\node[circle,minimum size=0.4cm] (b) at (0.1,0){};
\fill (b.90) circle (\x) (b.0) circle (\x) (b.180) circle (\x) (b.270) circle (\x);
\draw[->] (a.90) -- ++(0,0.5) -- ++(0.5,0) node[right,ellipse,draw,inner sep=0.5pt](mv){M.V.};
\draw[->] (a.270) -- ++(0,-0.5) -- node[pos=0.5,nosep] (evap){} ++(1,0) -- ++(0,0.815) -- (a.0);
\node[below right = of evap,draw,yshift=0.25cm] (syp){Pump};
\draw[->] (syp) -|(evap);
},%liquid injection right 4-way valve
pt/.pic={
\draw (0,0) -- ++(0.25,0) node[right,draw,circle,minimum size=0.5cm,font=\small,inner sep=0pt](a){P};
},%pressure transducer
jump/.style={
to path={
let \p1=(\tikztostart),\p2=(\tikztotarget),\n1={atan2(\y2-\y1,\x2-\x1)} in
(\tikztostart) -- ($($(\tikztostart)!#1!(\tikztotarget)$)!0.15cm!(\tikztostart)$)
arc[start angle=\n1+180,end angle=\n1,radius=0.15cm] -- (\tikztotarget)}
},
jump/.default={0.5},
mfc/.style={
draw,minimum width=1.75cm,minimum height=0.9cm,
text height=1.5ex
},
nosep/.style={
inner sep=0pt,
outer sep=0pt,
},%meeting-point
]
\node[mfc] (mfc1) {a};
\node[below = of mfc1,mfc] (mfc2) {\ce{b}};
\node[below = of mfc2,mfc] (mfc3) {\ce{c}};
\node[below = of mfc3,mfc] (mfc4) {\ce{d}};
\node[below = of mfc4,mfc] (mfc5) {\ce{e}};
\node[below = of mfc5,mfc] (mfc6) {\ce{f}};
\foreach \y in {1,2,...,6}{
\draw[->] (mfc\y.east) --++(0.5,0) node[right=12pt] (svmfcc\y){} node[right=24pt](svmfcr\y){};
\pic at (svmfcc\y){sv};
};
%line-1
\draw[->] (svmfcr1) -- node[pos=0.45,nosep](mpl1){} ++(1.5,0) -- pic[pos=0.4,-]{pt}++(0,0.75) -- ++(2,0) pic[right]{lifwv} node[right](l1){};
\foreach \y in {3,5,6} {
\draw[->] (svmfcr\y) -- ++(0.75,0);
};
\draw[->] (svmfcr6) ++(0.75,0) -- (mpl1);
%line-2
\draw[->] (svmfcr2) -- node[pos=0.75,nosep] (mpl2){} ++(1.5,0) -- pic[-,pos=0.4]{pt}++(0,-0.75) -- ++(2,0) pic[right]{lifwv} node[right](l2){};
\draw[->] (svmfcr4) to[jump=0.65] ++(1.16,0) -- (mpl2);
\end{tikzpicture}
\end{document}
更灵活的方法
这里有一个变体,可让您在--
路径和-|
/|-
路径之间进行选择,以及设置跳跃的位置、半径和方向。
当然可以更改样式名称。默认情况下,to[jump]
绘制一条直线,中间有跳转。例如,使用to[jump={-u|}]
可获得一条-|
路径,其中跳转位于路径的水平部分。代码中有更多示例,并带有注释。
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
% initial value
\pgfmathsetmacro{\jumpswap}{1}
\tikzset{
% set up keys for radius, position, swap
jump radius/.estore in=\jumpradius,
jump pos/.estore in=\jumppos,
jump swap/.code={\pgfmathsetmacro{\jumpswap}{\jumpswap*-1}},
jump radius=0.15cm,
jump pos=0.5,
% set up styles for the various to-paths
-u-/.style={ % straight line
to path={
let \p1=(\tikztostart),\p2=(\tikztotarget),\n1={atan2(\y2-\y1,\x2-\x1)} in
(\p1) -- ($($(\p1)!\jumppos!(\p2)$)!\jumpradius!(\p1)$)
arc[start angle=\n1+180,delta angle=-180*\jumpswap,radius=\jumpradius] -- (\p2)}
},
-u|/.style={ % -| path with jump on horizontal leg
to path={
let \p1=(\tikztostart),\p2=(\tikztostart-|\tikztotarget), \n1={atan2(\y2-\y1,\x2-\x1)} in
(\p1) -- ($($(\p1)!\jumppos!(\p2)$)!\jumpradius!(\p1)$)
arc[start angle=\n1+180,delta angle=-180*\jumpswap,radius=\jumpradius] --(\p2) -- (\tikztotarget)}
},
|u-/.style={ % |- path with jump on vertical leg
to path={
let \p1=(\tikztostart),\p2=(\tikztostart|-\tikztotarget), \n1={atan2(\y2-\y1,\x2-\x1)} in
(\p1) -- ($($(\p1)!\jumppos!(\p2)$)!\jumpradius!(\p1)$)
arc[start angle=\n1+180,delta angle=-180*\jumpswap,radius=\jumpradius] -- (\p2) -- (\tikztotarget)}
},
-|u/.style={ % -| path with jump on vertical leg
to path={
let \p1=(\tikztostart-|\tikztotarget),\p2=(\tikztotarget), \n1={atan2(\y2-\y1,\x2-\x1)} in
(\tikztostart) -- (\p1) -- ($($(\p1)!\jumppos!(\p2)$)!\jumpradius!(\p1)$)
arc[start angle=\n1+180,delta angle=-180*\jumpswap,radius=\jumpradius] -- (\p2)}
},
|-u/.style={ % |- path with jump on horizontal leg
to path={
let \p1=(\tikztostart|-\tikztotarget),\p2=(\tikztotarget), \n1={atan2(\y2-\y1,\x2-\x1)} in
(\tikztostart) -- (\p1) -- ($($(\p1)!\jumppos!(\p2)$)!\jumpradius!(\p1)$)
arc[start angle=\n1+180,delta angle=-180*\jumpswap,radius=\jumpradius] -- (\p2)}
},
% define the jump style, set it to use straight line by default
jump/.style={-u-,#1},
jump/.default={}
}
\begin{document}
\begin{tikzpicture}[
% use nodes with this style to highlight where segments meet
dot/.style={node contents={},inner sep=1pt,circle,fill=red}
]
\fill [blue!10] (-0.5,-2.5) rectangle (5.5,1.5);
\draw (0,0)
% default bump
to[jump] ++(1,0) node[dot]
% place bump on other side of line
to[jump={jump swap}] ++(1,0) node[dot]
% -| path, larger bump on horizontal leg
to[jump={-u|,jump radius=0.5cm}] ++(2,1) node[dot]
% -| path, bump at pos=0.7 along vertical leg
to[jump={-|u,jump pos=0.7}] ++(1,-1) node[dot]
% |- path, bump along vertical leg
to[jump={|u-}] ++(-2,-1) node[dot]
% |- path, larger bump on horizontal leg, other side of line
to[jump={|-u,jump radius=0.5cm,jump swap}] ++(-3,-1) node[dot]
to[jump] ++(1,1) node[dot]
to[jump={jump radius=3mm}] ++(-1,1) node[dot];
\end{tikzpicture}
\end{document}
答案2
思路:分两步绘制:
- 首先确定
jump
- 然后绘制到
jump
然后从jum
更远的地方
为此,您需要重新设计pic
跳转。参见下面的演示:
\documentclass[tikz, margin=3mm]{standalone}
\begin{document}
\begin{tikzpicture}[
jump/.pic = {
\draw[line cap=rect] (0.15,0) coordinate (-out)
arc (0:180:0.15) coordinate (-in);
},
]
\draw[red] (1.5,-1) -- + (0,2);
\path (0,0) -- pic (aux) {jump} (3,0);
\draw (0,0) -- (aux-in) (aux-out) -- (3,0);
\end{tikzpicture}
\end{document}
上述想法融入到你的姆韦:
\documentclass[11pt]{standalone}
\usepackage{lmodern}
\renewcommand*{\familydefault}{\sfdefault}
\usepackage{sfmath}
\usepackage[version=4]{mhchem}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,fit,positioning,intersections,shapes.geometric,
decorations,patterns,decorations.markings}
\tikzset{
every path/.style={thick},
every node/.style={
font={\normalsize},
align=center,
transform shape
},
}
\begin{document}
\begin{tikzpicture}[node distance=0.75cm]
\tikzset{
sv/.pic={
\def \x {0.43}
\node[draw,isosceles triangle,fill=none] (a) at (-\x,0) {};
\node[draw,isosceles triangle,shape border rotate=180,fill=none] at (\x,0){};
\draw[fill=none] (0,0) circle (0.22);
},%shutoff valve
lifwv/.pic={
\def \x {1pt}
\node[draw,circle,minimum size=0.6cm] (a) at (0,0){};
\node[circle,minimum size=0.4cm] (b) at (0.1,0){};
\fill (b.90) circle (\x) (b.0) circle (\x) (b.180) circle (\x) (b.270) circle (\x);
\draw[->] (a.90) -- ++(0,0.5) -- ++(0.5,0) node[right,ellipse,draw,inner sep=0.5pt](mv){M.V.};
\draw[->] (a.270) -- ++(0,-0.5) -- node[pos=0.5,nosep] (evap){} ++(1,0) -- ++(0,0.815) -- (a.0);
\node[below right = of evap,draw,yshift=0.25cm] (syp){Pump};
\draw[->] (syp) -|(evap);
},%liquid injection right 4-way valve
pt/.pic={
\draw (0,0) -- ++(0.25,0) node[right,draw,circle,minimum size=0.5cm,font=\small,inner sep=0pt](a){P};
},%pressure transducer
%---------------------------------------------------------------%
jump/.pic = { %%%% changed
\draw[line cap=rect] (0.15,0) coordinate (-out)
arc (0:180:0.15) coordinate (-in);
},
%---------------------------------------------------------------%
mfc/.style={
draw,minimum width=1.75cm,minimum height=0.9cm,
text height=1.5ex
},
nosep/.style={
inner sep=0pt,
outer sep=0pt,
},%meeting-point
}
\node[mfc] (mfc1) {a};
\node[below = of mfc1,mfc] (mfc2) {\ce{b}};
\node[below = of mfc2,mfc] (mfc3) {\ce{c}};
\node[below = of mfc3,mfc] (mfc4) {\ce{d}};
\node[below = of mfc4,mfc] (mfc5) {\ce{e}};
\node[below = of mfc5,mfc] (mfc6) {\ce{f}};
\foreach \y in {1,2,...,6}{
\draw[->] (mfc\y.east) --++(0.5,0) node[right=12pt] (svmfcc\y){} node[right=24pt](svmfcr\y){};
\pic at (svmfcc\y){sv};
};
%line-1
\draw[->] (svmfcr1) -- node[pos=0.45,nosep](mpl1){} ++(1.5,0) -- pic[pos=0.4,-]{pt}++(0,0.75) -- ++(2,0) pic[right]{lifwv} node[right](l1){};
\foreach \y in {3,5,6} {
\draw[->] (svmfcr\y) -- ++(0.75,0);
};
\draw[->] (svmfcr6) ++(0.75,0) -- (mpl1);
%line-2
\draw[->] (svmfcr2) -- node[pos=0.75,nosep] (mpl2){} ++(1.5,0) -- pic[-,pos=0.4]{pt}++(0,-0.75) -- ++(2,0) pic[right]{lifwv} node[right](l2){};
%---------------------------------------------------------------%
\path (svmfcr4) -- pic[pos=0.6] (aux) {jump} ++(1.16,0); %%%% added
\draw[->] (svmfcr4) -- (aux-in) (aux-out) -| (mpl2); %%%% changed
%---------------------------------------------------------------%
\end{tikzpicture}
\end{document}