TikZ:在电路中使用 --cycle

TikZ:在电路中使用 --cycle

为什么该--cycle命令在使用 TikZ 库绘制的电路中不起作用circuits.ee.IEC?手动绘制最后一个连接的问题是末端未连接。

问题
我把线画得很粗,以演示不连接的问题……

是否有可能修复此问题或者至少手动加入路径?

代码

\documentclass{minimal}

\usepackage{tikz}
\usetikzlibrary{circuits.ee.IEC}

\begin{document}
\begin{tikzpicture}[circuit ee IEC, line width=5pt]
\draw (0,0) -- ++(0,2) node [above] {without objects}%
    -- ++(4,0) -- ++(0,-2)%
    --cycle node [below] {works};

\draw (0,-4.5) to[voltage source] ++(0,2) node [above] {with -\/-cycle}%
    -- ++(4,0) to[resistor] ++(0,-2)%
    --cycle node [below] {no connection};

\draw (0,-9) to[voltage source] ++(0,2) node [above] {manually}%
    -- ++(4,0) to[resistor] ++(0,-2)%
    -- ++(-4,0) node [below] {not joined};
\end{tikzpicture}
\end{document}

答案1

手动的关于--cycle操作:

此操作会从当前点到移动至操作指定的最后一个点添加一条直线。请注意,这不一定是路径的起点。此外,还会创建平滑连接。

因此,显然在添加电压源和电阻时会有一个移动操作(这完全合理),因此实际上进行了循环,只是在这种情况下它只是在已经存在的线上画一条线回到电阻的末端。

我想不出任何方法来修复此行为,必须在 pgf 路径中进行移动才能“跳过”电阻器(和电压源)的符号。不过,我们可以在手动添加线时执行一个小技巧来获得正确的连接。基本上,我们所做的只是在已经存在的线上方画一条短线,这将在已经存在的线之上创建一个平滑的连接。

\documentclass{minimal}

\usepackage{tikz}
\usetikzlibrary{circuits.ee.IEC}

\begin{document}
\begin{tikzpicture}[circuit ee IEC, line width=5pt]
\draw (0,0) -- ++(0,2) node [above] {without objects}%
    -- ++(4,0) -- ++(0,-2)%
    --cycle node [below] {works};

\draw (0,-4.5) to[voltage source] ++(0,2) node [above] {with -\/-cycle}%
    -- ++(4,0) to[resistor] ++(0,-2)%
    --cycle node [below] {no connection};

\draw (0,-9) to[voltage source] ++(0,2) node [above] {manually}%
    -- ++(4,0) to[resistor] ++(0,-2)%
    -- ++(-4,0) node [below] {now joined} -- ++(0,0.1);
\end{tikzpicture}
\end{document}

生成的文档如下:

电路中的连接线

答案2

马丁的评论是正确的。--cycle语法从路径上的当前点到起点绘制一条直线最后一个组件。组件表示连续路径,因此由最后一个 标记moveto。实际实现由驱动程序或渲染器处理,因此 TikZ 不会控制在这种情况下如何处理角。

你试图做的事情的问题是你的路径被移动打断了。符号是使用节点放置的,必须打破路径才能绕过它们。如果我们检查实际定义的路径,这一点就很清楚了。如果我们以你的中间例子为例,看看实际的路径,我们得到:

\pgfsyssoftpath@movetotoken {0.0pt}{-128.03734pt}
\pgfsyssoftpath@linetotoken {0.0pt}{-109.08456pt}
\pgfsyssoftpath@movetotoken {0.0pt}{-90.08456pt}
\pgfsyssoftpath@linetotoken {0.0001pt}{-71.13185pt}
\pgfsyssoftpath@linetotoken {0.0001pt}{-71.13185pt}
\pgfsyssoftpath@linetotoken {113.81097pt}{-71.13185pt}
\pgfsyssoftpath@linetotoken {113.81097pt{-83.08463pt}
\pgfsyssoftpath@movetotoken {113.81097pt}{-116.08463pt}
\pgfsyssoftpath@linetotoken {113.81108pt}{-128.03734pt}
\pgfsyssoftpath@linetotoken {113.81108pt}{-128.03734pt}
\pgfsyssoftpath@closepathtoken {113.81097pt}{-116.08463pt}

因此,我们从 a 开始moveto(每条路径都以 开始moveto),然后画一条直线。接着是另一个moveto:这是跳过电压源的移动。然后我们得到一个lineto到角落。(事实上,我们得到了两个lineto,但第二个实际上是一个 NOP。大概有一些复杂的情况会发挥作用。)我们的下一个旅程是穿过顶部,然后我们开始下降。再次,我们中断旅程以腾出空间放置电阻器,然后在角落完成向下的部分(再次使用双lineto)。最后一个阶段是closepath关闭路径的(一定是个天才想出了名称)。的坐标closepath实际上并未使用,但可以向用户指示收盘线应该去往何处。在本例中,它位于电阻器的底部。由于这条线已经绘制,因此我们不会注意到这一点。

仅绘制路径就会产生以下红线:

路径

当然,我们在这里看不到,closepath因为它位于已绘制的路径之上。如果我们取出电阻器,那么我们就可以看到它的closepath实际作用:

整个路径

也许很难看清,但是封闭的道路确实封闭了。

这里的困难在于--cycle总是产生一个关闭路径。但这不是你想要的。你想要的是将结尾与开头连接起来。具体如何做到这一点取决于你希望解决方案的自动化程度和忠实程度。“自动”是相当明显的,“忠实”可能不那么明显。我的意思是你是否希望路径实际上或者模拟是否足够。

如果模拟足够,并且所有角都是直角,那么简单line cap=rect就足够了。这可确保线条末端突出线宽的一半。比较:

带矩形线帽的角

不幸的是,在我使用你的代码进行的测试中,无穷小的线条会干扰这一点,导致我在右下角没有得到一个干净的角落。(但是,我使用你的代码所以我怀疑我们有不同的 PGF 版本,并且这对您来说可能是一个不错的解决方案......不挂断:现在上传了图片后,我发现右下角没有干净的角落是由于我的 PDF 查看器造成的!)

带矩形线帽的电路

顺便说一句,请注意,这还会修复图片中“电线”和“符号”之间的小白线。通常这些白线是看不到的 - 它们之所以存在,是因为线条太粗,而且线条没有准确地放在正确的位置。

去做这个自动地忠实我们要做的就是找到路径并对其进行一些处理。我们必须找到初始组件(向上延伸的那部分)并将其与最后一个组件连接起来,这样路径现在就从电阻发出的位开始。这在低级代码中完全可行,而且我的spath库中拥有所有部分,只需以合理的方式将它们组合在一起即可。

相关内容