我希望能够在 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
不,不是。您需要加载tikz
TikZ 包和(如您所做)其中一个装饰库。
但首先要做的事情是,你可以把所有的路径写成一条路径(如果我们暂时忽略修饰的话):
\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}