我正在尝试调试一个问题,circuitikz
我已经能够将其简化为这个 MWE --- 如果它不那么短,请原谅......
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\pgfdeclareshape{sline}{
\anchor{center}{
\pgfpointorigin
}
\anchor{left}{\pgf@x=-0.5cm\pgf@y=0pt}
\anchor{right}{\pgf@x=0.5cm\pgf@y=0pt}
\backgroundpath{
\pgfscope
\pgfsetcolor{red}
\pgfpathmoveto{\pgfpoint{-0.5cm}{0pt}}
\pgfpathlineto{\pgfpoint{0.5cm}{0pt}}
\pgfusepath{draw}
\endpgfscope
}
}
\def\goforpaths{
\pgfextra{
\pgfmathanglebetweenpoints{\tikztostart}{\tikztotarget}
\edef\mydirection{\pgfmathresult}%Calculate direction(angle) of path
}
($(\tikztostart)!0.5!(\tikztotarget)$) node[sline, rotate=\mydirection](N){}
(\tikztostart) -- (N.left) (N.right) -- (\tikztotarget)
\tikztonodes
}
\tikzset{slineto/.style={/tikz/to path=\goforpaths}}
\makeatother
\begin{document}
\begin{tikzpicture}[
scale=1.2,
% scale=2
]
\draw (24,-1) to[slineto] ++(0,2);
\end{tikzpicture}
\end{document}
MWE 模仿了circuitikz
沿路径放置组件的操作;在这种情况下,组件是一条简单的红线。
现在,当比例因子不是整数时,我在连接中出现了这种非常奇怪的行为:
(请注意,我使用不同的 PDF 查看器进行了测试)。
对于整数比例因子或无比例,结果是完美的:
(这是与 相同的代码片段scale=2
)。另外,如果将24
坐标中的更改为0
,问题几乎消失。
我想这是坐标计算中积累的错误——但这很奇怪,所以我我做错了非常高。有人能发现我的错误在哪里吗?
答案1
问题是\pgfmathreciprocal@
,它被用来反转转换。在下面展示本地版本之前,让我先介绍一个全局修复,它取代了\pgfmathreciprocal@
到处通过fpu
变体。虽然这在手头的例子中是可以的,但可能不是在所有可能的例子中都可以。(天真地,人们可能认为它应该总是在普通的 Ti 中起作用。)钾Z,但魔鬼就在细节中。无论如何,下面可以找到绝对安全的本地版本。
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{fpu}
\makeatletter
\def\pgfmathreciprocal@#1{%
\begingroup
% FIXME optimize
\pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}%
\pgfmathparse{1/#1}%
\pgfmath@smuggleone\pgfmathresult
\endgroup
}%
\pgfdeclareshape{sline}{
\anchor{center}{
\pgfpointorigin
}
\anchor{left}{\pgf@x=-0.5cm\pgf@y=0pt}
\anchor{right}{\pgf@x=0.5cm\pgf@y=0pt}
\backgroundpath{
\pgfscope
\pgfsetcolor{red}
\pgfpathmoveto{\pgfpoint{-0.5cm}{0pt}}
\pgfpathlineto{\pgfpoint{0.5cm}{0pt}}
\pgfusepath{draw}
\endpgfscope
}
}
\def\goforpaths{
let \p1=($(\tikztostart)-(\tikztotarget)$),\n1={atan2(\y1,\x1)} in
($(\tikztostart)!0.5!(\tikztotarget)$)
node[sline, rotate=\n1,anchor=center](N){}
(\tikztostart) -- (N.left)
(N.right) -- (\tikztotarget)
\tikztonodes
}
\tikzset{slineto/.style={/tikz/to path=\goforpaths}}
\makeatother
\begin{document}
\begin{tikzpicture}[
scale=1.2,
%scale=2
]
\draw (24,-1) to[slineto] ++(0,2);
\end{tikzpicture}
\end{document}
还请注意,我使用 calc 语法来计算旋转角度。这与问题无关,我并不是说这种方法更好。
您始终可以做的是将更改限制在某个范围或路径内。此版本不会造成损害。
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{fpu}
\makeatletter
\tikzset{use fpu reciprocal/.code={%
\def\pgfmathreciprocal@##1{%
\begingroup
% FIXME optimize
\pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}%
\pgfmathparse{1/##1}%
\pgfmath@smuggleone\pgfmathresult
\endgroup
}}}%
\pgfdeclareshape{sline}{
\anchor{center}{
\pgfpointorigin
}
\anchor{left}{\pgf@x=-0.5cm\pgf@y=0pt}
\anchor{right}{\pgf@x=0.5cm\pgf@y=0pt}
\backgroundpath{
\pgfscope
\pgfsetcolor{red}
\pgfpathmoveto{\pgfpoint{-0.5cm}{0pt}}
\pgfpathlineto{\pgfpoint{0.5cm}{0pt}}
\pgfusepath{draw}
\endpgfscope
}
}
\def\goforpaths{
\pgfextra{
\pgfmathanglebetweenpoints{\tikztostart}{\tikztotarget}
\edef\mydirection{\pgfmathresult}%Calculate direction(angle) of path
}
($(\tikztostart)!0.5!(\tikztotarget)$) node[sline, rotate=\mydirection](N){}
(\tikztostart) -- (N.left) (N.right) -- (\tikztotarget)
\tikztonodes
}
\tikzset{slineto/.style={/tikz/to path=\goforpaths}}
\makeatother
\begin{document}
\begin{tikzpicture}[
scale=1.2,
%scale=2
]
\draw[use fpu reciprocal] (24,-1) to[slineto] ++(0,2);
\end{tikzpicture}
\end{document}
您可以将其构建到您真正想做的事情的定义中。
(心里想:也许对其他核心功能使用这个技巧可以让我们通过在本地安装这些更改来摆脱dimension too large
困扰装饰和非线性转换的问题?)