我正在尝试创建一些基本的光学元件(在本例中是分束器)以用于 PGF/TikZ。好吧,由于我对 PGF/TikZ(甚至 LaTeX)还很陌生,所以有些事情我不太确定。我想要创建的形状几乎与预定义的矩形形状相同,只是包含一条额外的对角线。我的问题是,我是否可以只将一些代码附加到从预定义形状继承的背景路径而不覆盖它们,而不是将所有预定义的背景路径代码与我的附加代码一起复制?
虽然我从 pgfmanual 版本 2.10 第 631 页的示例中获得了一些想法。我已经创建的形状似乎运行良好
我使用的代码是:
\documentclass{article}
\usepackage{pgf} % pgfcore, modules shapes and plot
\usepackage{tikz}
\makeatletter
\pgfdeclareshape{bs}{
\inheritsavedanchors[from=rectangle]
\inheritanchorborder[from=rectangle]
\inheritbehindbackgroundpath[from=rectangle]
\inheritbackgroundpath[from=rectangle]
\inheritbeforebackgroundpath[from=rectangle]
\inheritbehindforegroundpath[from=rectangle]
\inheritforegroundpath[from=rectangle]
\inheritbeforeforegroundpath[from=rectangle]
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
\backgroundpath{
% store lower left in xa/ya and upper right in xb/yb
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
% construct main path
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
\pgfpathclose
% add diagonal
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw[help lines] (-1,-1) grid (1,1);
\node[shape=bs,draw,minimum size=1cm,label=below:BS] (x) {};
\end{tikzpicture}
\end{document}
但是,如果我尝试删除构造矩形的代码,只在\backgroundpath{}
环境中保留对角线代码。我得到了如下形状。似乎此操作覆盖了继承的背景路径。
上述形状的代码是:
\documentclass{article}
\usepackage{pgf} % pgfcore, modules shapes and plot
\usepackage{tikz}
\makeatletter
\pgfdeclareshape{bs}{
\inheritsavedanchors[from=rectangle]
\inheritanchorborder[from=rectangle]
\inheritbehindbackgroundpath[from=rectangle]
\inheritbackgroundpath[from=rectangle]
\inheritbeforebackgroundpath[from=rectangle]
\inheritbehindforegroundpath[from=rectangle]
\inheritforegroundpath[from=rectangle]
\inheritbeforeforegroundpath[from=rectangle]
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
\backgroundpath{
% store lower left in xa/ya and upper right in xb/yb
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
% construct main path
%\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
%\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
%\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
%\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
%\pgfpathclose
% add diagonal
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw[help lines] (-1,-1) grid (1,1);
\node[shape=bs,draw,minimum size=1cm,label=below:BS] (x) {};
\end{tikzpicture}
\end{document}
由于 Till Tantau 表示,形状矩形的代码实际上可能非常复杂(因此可能更稳定、更快、更灵活?),所以我尝试继承原始背景路径并附加我的额外对角线代码。任何建议或帮助都将不胜感激:)
答案1
当\backgroundpath
在形状定义中使用时,它将覆盖任何先前继承或其他的背景路径规范。
矩形背景路径的实际代码是:
\pgfpathrectanglecorners
{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}
{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
这看起来有点不友好,但只是考虑了outer xsep
和outer ysep
键的值。
可以将代码复制/粘贴到\backgroundpath
新形状的代码中,或者可以使用内部命令\pgf@sh@bg@rectangle
(它包含矩形的背景路径的代码)。
无论哪种方式,建议的附加对角线也必须考虑到outer sep
。我认为完成整个事情的更有效的方法(即更少调用PGF
数学引擎)是:
\pgfextract@process\outersep{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}%
{\pgfkeysvalueof{/pgf/outer ysep}}}%
\pgfextract@process\southwest{\pgfpointadd{\southwest}{\outersep}}%
\pgfextract@process\northeast{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\outersep}}}%
\pgfpathrectanglecorners{\southwest}{\northeast}%
\pgfpathmoveto{\southwest}%
\pgfpathlineto{\northeast}%