定义在 tikzdiagrams 中绘制反馈回路的线条样式

定义在 tikzdiagrams 中绘制反馈回路的线条样式

我希望能够在 tikzdiagram 中绘制一条表示反馈回路的线,如下所示

反馈回路

使用类似命令(但不一定完全类似)

\draw[feedback](0,0)to(-1,-1);

我希望环的形状能够根据端点的位置进行调整。例如,我希望直线部分始终位于两个端点中最低点的下方一点(例如,位于最低点下方 1 厘米),并且环由两个半圆和一条直线组成。

我希望这个命令能够与节点以及坐标一起作为输入。

我用来生成这张图片的代码是:

\usepackage{fontawesome} % I think this is necessary for markings
\usetikzlibrary{decorations.markings} % markings
\tikzset{->-/.style={decoration={markings, mark=at position 0.5 with {\arrow{>>}}}, postaction={decorate}}}

\begin{document}
\begin{tikzpicture}
  \draw[out=0,in=90](0,0)to(1,-1)[out=-90,in=0]to(0,-2);
  \draw[out=180,in=0,->-](0,-2)to(-1,-2);
  \draw[out=180,in=-90](-1,-2)to(-1.5,-1.5)[out=90,in=180]to(-1,-1);
\end{tikzpicture}
\end{document}

如何使用 tikzset 定义线条样式或为其定义 \newcommand?

答案1

\usepackage{fontawesome} % I think this is necessary for markings

不,不是。您需要加载tikzTikZ 包和(如您所做)其中一个装饰库。

但首先要做的事情是,你可以把所有的路径写成一条路径(如果我们暂时忽略修饰的话):

\begin{tikzpicture}
\draw (0,0) to[out=  0, in= 90] ( 1,-1)
            to[out=-90, in=  0] ( 0,-2)
            --                  (-1,-2)
            to[out=180, in=-90] (-1.5, -1.5)
            to[out= 90, in=180] (-1,-1);
\path[->-] (0,-2) -- (-1,-2);
\end{tikzpicture}

我们也可以只用一个半圆来写to,但looseness = 2添加或者我们可以使用arc手术

我们会这样做,因为这样以后的事情就变得更容易了:

\begin{tikzpicture}
\draw[delta angle=-180]
      (0,0) arc[start angle= 90, radius=1] coordinate (endofarc)
            --                  (-1,-2)    coordinate (endofstraight)
            arc[start angle=-90, radius=.5];
\path[->-] (endofarc) -- (endofstraight);
\end{tikzpicture}

现在我们必须对其进行参数化。

假设您,即用户,想要让直线部分#1位于目标点下方(或上方)固定距离处。

第二个半圆的半径为(#1)/2,第一个半圆的半径为两个坐标之间的差值方向加#1和一半的一切。

然后我们只需要找出所需的角度(是的,to这会更容易,因为我们只需指定方向,但如果我没看错的话,我们需要计算更多的中间点)。为此,我设置了一些简单的测试,scalar功能是必要的,因为否则它会返回0pt(对于 false)和1pt(对于 true),但以下ifthenelse(通过?/ :)不再喜欢那样了。

现在,虽然 TikZ 支持仅装饰路径的一部分使用的装饰会破坏该段,我看不出有什么办法postaction。但我们可以edge在里面使用to path,因为这在所有意图和目的上都是一条单独的路径。line to指定所需的路径(通常是默认路径,但由于我们在里面,to path否则会导致无限循环)。

尽管如此,装饰破坏了我所采取的安全措施,path only从而禁用了路径上的所有操作。


我们可以扩展它,以便#1没有单位的参数指定坐标之间的垂直距离的因子,但这需要更多的工作,因为我们需要#1先进行评估才能进行这些计算。

作为hpekristiansen 建议我将\tikztonodes在该--部分之后添加内容,以便您可以沿着直线部分放置节点。


decorations.markings我们可以使用pic来沿路径放置箭头,而不是。为此,只\pgfarrowdraw需要 ,它(显然,没有文档说明)会在当前位置绘制指定的箭头。

代碼(附有decorations.markings

\documentclass[tikz, border=2.5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{
  decorations.markings, % → markings decoration
  calc,                 % → let … in
}
\tikzset{
  ->-/.style={
    decoration={
      markings,
      mark=at position 0.5 with {\arrow{>>}}
    },
    postaction=decorate
  },
  feedback/.default=1cm,
  feedback/.style={% #1 a distance
    to path={
      let \p{start}       = (\tikztostart),
          \p{target}      = (\tikztotarget),
          \n{radiusA}     = {(#1)/2+abs(\y{start}-\y{target})/2},
          \n{firstArcUp}  = {scalar(\y{start}>\y{target})},
          \n{arcClockwise}= {scalar(\x{start}>\x{target}!=\y{start}>\y{target})}
      in
      arc[start angle=(\n{firstArcUp}?90:-90),
          delta angle=(\n{arcClockwise}?-180:180),
          radius=\n{radiusA}]
      coordinate (end of feedback arc)
      -- (end of feedback arc-|\tikztotarget)
      \tikztonodes
      coordinate (end of feedback straight)
      arc[start angle=(\n{firstArcUp}?-90:90),
          delta angle=(\n{arcClockwise}?-180:180)*((#1)<0?-1:1),
          radius={(#1)/2}]
      (end of feedback arc) edge[line to, path only, ->-]
      (end of feedback straight)
    }
  }
}
\begin{document}
\begin{tikzpicture}
\draw[help lines] (-2.75, -2.5) grid (1.25, .75);
\draw ( 0, 0) to[feedback      ] node[below=2pt, scale=.4] {Whee!} (-1  , -1  );
\draw (-1,-1) to[feedback=-.5cm]                                   (-2.5,   .5);
\end{tikzpicture}
\end{document}

代码(无修饰)

\documentclass[tikz, border=2.5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc} % → let … in
\tikzset{
  feedback/.default=1cm,
  feedback/.style={% #1 a distance
    to path={
      let \p{start}       = (\tikztostart),
          \p{target}      = (\tikztotarget),
          \n{radiusA}     = {(#1)/2+abs(\y{start}-\y{target})/2},
          \n{firstArcUp}  = {scalar(\y{start}>\y{target})},
          \n{arcClockwise}= {scalar(\x{start}>\x{target}!=\y{start}>\y{target})}
      in
      arc[start angle=(\n{firstArcUp}?90:-90),
          delta angle=(\n{arcClockwise}?-180:180),
          radius=\n{radiusA}]
      coordinate (end of feedback arc)
      -- (end of feedback arc-|\tikztotarget)
      pic[midway, sloped, allow upside down] {code=\pgfarrowdraw{>>}}
      \tikztonodes
      coordinate (end of feedback straight)
      arc[start angle=(\n{firstArcUp}?-90:90),
          delta angle=(\n{arcClockwise}?-180:180)*((#1)<0?-1:1),
          radius={(#1)/2}]}}}
\begin{document}
\begin{tikzpicture}
\draw[help lines] (-2.75, -2.5) grid (1.25, .75);
\draw ( 0, 0) to[feedback      ] node[below=2pt, scale=.4] {Whee!} (-1  , -1  );
\draw (-1,-1) to[feedback=-.5cm]                                   (-2.5,   .5);
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

答案2

我有另一个(更简单的?)代码来生成埃琳娜的照片:

\documentclass[12pt,a4paper]{article}
\usepackage{tikz}
\begin{document}
    \begin{tikzpicture}
        \draw (3,2) arc (90:-90:2); 
        \draw[->>-] (3.1,-2)--(2,-2);
        \draw (2,-2)--(1,-2) arc (270:90:1);    
    \end{tikzpicture}
\end{document}

输出:

在此处输入图片描述

相关内容