更灵活的方法

更灵活的方法

我正在尝试使用创建我的钻机的流程图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);\tikztostarta,而\tikztotargetb

开始部分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 厘米、朝向起点的坐标。ab

从该点开始,使用计算出的角度绘制圆弧,并以 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}

在此处输入图片描述

相关内容