是否存在一种机制可以提供尺寸或比例作为符号实例的输入?

是否存在一种机制可以提供尺寸或比例作为符号实例的输入?

我意识到,符号在设计上主要具有静态特征。注释是例外。符号的特定实例可能具有与其关联的属性值,这些属性值在实例之间是可变的。例如,电阻器在实例之间的背景路径上具有相同的线,但我们可以通过字符串指示不同的值,财产=价值 单元,放置在一个节点上。

我想创建一个类似电阻器的符号,它有两个部分;主体通过垂直线简单地分为两个部分。但是,我希望能够调整垂直线的相对水平位置,以便可以改变隔间的相对宽度。我不知道有什么机制可以允许将比例值传递给符号的特定实例。也许我们可以用调整符号整体大小的相同方式调整垂直线/分隔线的位置。

代码

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\usetikzlibrary{circuits,circuits.ee.IEC}
\makeatletter
\pgfdeclareshape{symbol shape}{%
    \inheritsavedanchors[from=rectangle ee]
    \inheritanchor[from=rectangle ee]{center}
    \inheritanchor[from=rectangle ee]{north}
    \inheritanchor[from=rectangle ee]{south}
    \inheritanchor[from=rectangle ee]{east}
    \inheritanchor[from=rectangle ee]{west}
    \inheritanchor[from=rectangle ee]{north east}
    \inheritanchor[from=rectangle ee]{north west}
    \inheritanchor[from=rectangle ee]{south east}
    \inheritanchor[from=rectangle ee]{south west}
    \inheritanchor[from=rectangle ee]{input}
    \inheritanchor[from=rectangle ee]{output}
    \inheritanchorborder[from=rectangle ee]
    \inheritbackgroundpath[from=rectangle ee]
    \behindbackgroundpath{%
    \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}%
    \pgf@xa\pgf@x\pgf@ya\pgf@y
    \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}%
    \pgf@xb\pgf@x\pgf@yb\pgf@y
    \pgfpathmoveto{\pgfqpoint{\pgf@xa}{0pt}}%
    \pgfpathlineto{\pgfqpoint{1.5\pgf@xa}{0pt}}%
    \pgfpathmoveto{\pgfqpoint{\pgf@xb}{0pt}}%
    \pgfpathlineto{\pgfqpoint{1.5\pgf@xb}{0pt}}%
    \pgfpathmoveto{\pgfqpoint{0pt}{\pgf@ya}}%
    \pgfpathlineto{\pgfqpoint{0pt}{\pgf@yb}}%
    }
}
\makeatother
\tikzset{
    circuit declare symbol=symbol,
    set symbol graphic={
    shape=symbol shape,
    draw,
    transform shape,
    circuit symbol size=width 8.12936 height 2.03233,
}
}
\begin{document}
\begin{tikzpicture}[circuit ee IEC]
\node[symbol] at (0,0) (thesymbol) {};
\end{tikzpicture}
\end{document}

垂直分隔线目前由以下代码定义:

\pgfpathmoveto{\pgfqpoint{0pt}{\pgf@ya}}%
\pgfpathlineto{\pgfqpoint{0pt}{\pgf@yb}}%

\pgfqpoint 命令的 x-component/first 参数是我感兴趣的变量。适当的下限和上限是 \pgf@xa 和 \pgf@xb。

请注意,此处的代码主要由论坛用户 Qrrbrbirlbel 编写,用于回答问题。

欢迎任何建议。

答案1

以下代码使用键的值/pgf/symbol shape ratio(初始值为.5)来计算X垂直条的值。进行了额外的校正,以便垂直线以及水平附加线不会越过边界线,而只会接触边界线(如果使用透明度,这将受到赞赏)。我还更改了水平线的定义,使它们始终具有相同的长度(即形状宽度的四分之一)。同样,这实际上只在(可能不存在的)形状与文本一起使用的情况下才重要(如下面的示例),但这并没有真正造成伤害。

.west我没有改变和锚点的定义.east。额外的水平线将不会被识别为放置和连接。

作为一个小练习,我添加了三个锚点

  • bar north
  • bar south, 和
  • bar center

它们的位置可以在下面的示例图中观察到。如果你不需要它们,你可以简单地删除命令\anchor

通过 定义的锚点\anchor将在访问时计算,而不是在绘制形状时计算。对于形状rectangle(以及通过继承我们的形状),只保存\northeast\southwest锚点。其他每个锚点都可以根据这两个计算。因为symbol shape ratio在我们访问锚点时 可能已经改变,所以bar *我们将当前值(对于这个形状)保存在 中\savedmacro

补充说明一下:可以通过以下代码检查输入比率是否介于0.0和之间。1.0

\ifdim\barratio pt<0pt\relax
  % the ratio is < 0
\else\ifdim\barratio pt>1pt\relax
    % the ratio is > 1
  \fi
\fi

代码

\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{circuits,circuits.ee.IEC}
\makeatletter
\pgfkeys{/pgf/symbol shape ratio/.initial=.5}
\pgfdeclareshape{symbol shape}{%
    \savedmacro\barratio{%
      \pgfmathsetmacro\barratio{\pgfkeysvalueof{/pgf/symbol shape ratio}}%
      \ifdim\barratio pt<0pt\relax
        % the ratio is < 0
      \else\ifdim\barratio pt>1pt\relax
          % the ratio is > 1
        \fi
      \fi
    }
    \inheritsavedanchors[from=rectangle ee]
    \inheritanchor[from=rectangle ee]{center}
    \inheritanchor[from=rectangle ee]{north}
    \inheritanchor[from=rectangle ee]{south}
    \inheritanchor[from=rectangle ee]{east}
    \inheritanchor[from=rectangle ee]{west}
    \inheritanchor[from=rectangle ee]{north east}
    \inheritanchor[from=rectangle ee]{north west}
    \inheritanchor[from=rectangle ee]{south east}
    \inheritanchor[from=rectangle ee]{south west}
    \inheritanchor[from=rectangle ee]{input}
    \inheritanchor[from=rectangle ee]{output}
    \anchor{bar north}{%
      \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{0pt}}}%
      \pgf@xa\pgf@x
      \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{0pt}}}}%
      \advance\pgf@x-\pgf@xa
      \advance\pgf@xa\barratio\pgf@x
      \pgf@x\pgf@xa
    }
    \anchor{bar south}{%
      \pgfmathsetmacro\pgf@tempa{\pgfkeysvalueof{/pgf/symbol shape ratio}}%
      \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{0pt}}}%
      \pgf@xa\pgf@x\pgf@ya\pgf@y
      \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{0pt}}}}%
      \advance\pgf@x-\pgf@xa
      \advance\pgf@xa\barratio\pgf@x
      \pgf@x\pgf@xa
      \pgf@y\pgf@ya
    }
    \anchor{bar center}{%
      \pgfmathsetmacro\pgf@tempa{\pgfkeysvalueof{/pgf/symbol shape ratio}}%
      \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{0pt}}}%
      \pgf@xa\pgf@x\[email protected]\pgf@y
      \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{0pt}}}}%
      \advance\pgf@x-\pgf@xa\[email protected]\pgf@y
      \advance\pgf@xa\barratio\pgf@x
      \pgf@x\pgf@xa
      \advance\pgf@y\pgf@ya
    }
    \inheritanchorborder[from=rectangle ee]
    \inheritbackgroundpath[from=rectangle ee]
    \behindbackgroundpath{%
      \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}%
      \pgf@xa\pgf@x\pgf@ya\pgf@y
      \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}%
      \pgf@xb\pgf@x\pgf@yb\pgf@y
      % The center point: c = .5 * (a + b)
      \[email protected]\pgf@xb
      \advance\pgf@xc+.5\pgf@xa
      \[email protected]\pgf@yb
      \advance\pgf@yc+.5\pgf@ya
      % we don't want to overdraw lines and subtract/add half the line width (not affected by outer seps)
      \pgfutil@tempdima\pgf@xa
      \advance\[email protected]\pgflinewidth
      \[email protected]\pgf@xc
      \advance\[email protected]\pgf@xa
      \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima}{\pgf@yc}}%
      \pgfpathlineto{\pgfqpoint{\pgfutil@tempdimb}{\pgf@yc}}%
      \pgfutil@tempdima\pgf@xb
      \advance\pgfutil@tempdima+.5\pgflinewidth
      \[email protected]\pgf@xc
      \advance\[email protected]\pgf@xb
      \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima}{\pgf@yc}}%
      \pgfpathlineto{\pgfqpoint{\pgfutil@tempdimb}{\pgf@yc}}%
%
      \advance\pgf@xb-\pgf@xa%                                              \pgf@xb contains the width
      \advance\pgf@xa\barratio\pgf@xb%                                     left x value + ratio*width
      \advance\[email protected]\pgflinewidth
      \advance\[email protected]\pgflinewidth
      \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
      \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}%
      \pgfsetbuttcap
      \pgfusepathqstroke
    }%
}
\makeatother
\tikzset{
  circuit declare symbol=symbol,
  set symbol graphic={
    shape=symbol shape,
    draw,
    transform shape,
    circuit symbol size=width 8.12936 height 2.03233,
  }
}
\begin{document}
\foreach \Ratio in {0,5,10,...,100,100,95,90,...,0}{% will typeset 42 pages!
\begin{tikzpicture}[circuit ee IEC]
\node[symbol, symbol shape ratio=.01*\Ratio] at (0,0) (thesymbol) {\Ratio};
\path[<-,blue] (thesymbol.bar north) edge node[above,inner sep=+0pt,at end]{\tiny\ttfamily .bar north} ++ (0,.25)
               (thesymbol.bar south) edge node[below,inner sep=+0pt,at end]{\tiny\ttfamily .bar south} ++ (0,-.25);
\draw[blue] plot[mark=x,mark size=1pt] (thesymbol.bar center);
\end{tikzpicture}}
\end{document}

输出

在此处输入图片描述

相关内容