![使用带有变量的仅限形式模式:可能是 TikZ 错误](https://linux22.com/image/259012/%E4%BD%BF%E7%94%A8%E5%B8%A6%E6%9C%89%E5%8F%98%E9%87%8F%E7%9A%84%E4%BB%85%E9%99%90%E5%BD%A2%E5%BC%8F%E6%A8%A1%E5%BC%8F%EF%BC%9A%E5%8F%AF%E8%83%BD%E6%98%AF%20TikZ%20%E9%94%99%E8%AF%AF.png)
当我尝试在 TikZ 中使用可变图案颜色时,我发现它似乎不起作用。这是一个最小的工作示例:
\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}
%
%
\tikzset{slope/.store in=\slope}
%
\pgfdeclarepatternformonly[\slope]{slant lines}
{\pgfpoint{-.1mm/\slope}{-.1mm}}{\pgfpoint{1.1mm/\slope}{1.1mm}}
{\pgfpoint{1mm/\slope}{1mm}}
{
\pgfsetlinewidth{0.4pt}
\pgfpathmoveto{\pgfpoint{-.1mm/\slope}{-.1mm}}
\pgfpathlineto{\pgfpoint{1.1mm/\slope}{1.1mm}}
\pgfusepath{stroke}
}
%
%
\newcommand{\theslope}{0.7}
%
\pgfdeclarepatternformonly{diagonal lines}
{\pgfpoint{-.1mm/\theslope}{-.1mm}}{\pgfpoint{1.1mm/\theslope}{1.1mm}}
{\pgfpoint{1mm/\theslope}{1mm}}
{
\pgfsetlinewidth{0.4pt}
\pgfpathmoveto{\pgfpoint{-.1mm/\theslope}{-.1mm}}
\pgfpathlineto{\pgfpoint{1.1mm/\theslope}{1.1mm}}
\pgfusepath{stroke}
}
%
%
\begin{document}
\begin{tikzpicture}
\draw[pattern=diagonal lines,pattern color=blue] (0,0) rectangle (5,5);
\tikzset{every path/.append style={xshift=6cm}}
\draw[pattern=slant lines,pattern color=blue,slope=0.7] (0,0) rectangle (5,5);
\end{tikzpicture}
\end{document}
输出如下所示:
如果我理解正确的话,两个方块都应该用蓝色对角线填充。但对于可变斜率模式,该pattern color=blue
选项似乎被忽略了。
我是不是做错了什么,还是这真的是一个 bug?无论是哪种情况,我都有合理的方法可以改正吗?
答案1
摘自手册第 162 页,因此,仅有形式的图案本身没有任何颜色,但在使用时将使用当前图案颜色作为其颜色。
原因是,没有变量的纯形式图案声明被冻结,因此 TikZ 可以预先设置图案颜色,图案将继承该笔触颜色。但是,带有变量的图案不会被冻结,每次调用时都会重新评估。因此,每次都应该独立设置颜色。正如 Qrrbirlbel 的回答,应该在创建图案时为图案提供颜色。
\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}
\tikzset{
slope/.code={\edef\slope{#1}},
slope/.default=0.5,
slope
}
\makeatletter
\pgfdeclarepatternformonly[\tikz@pattern@color,\slope]{slant lines}
{\pgfpoint{-.1mm/\slope}{-.1mm}}
{\pgfpoint{1.1mm/\slope}{1.1mm}}
{\pgfpoint{1mm/\slope}{1mm}}
{
\pgfsetlinewidth{0.4pt}
\pgfpathmoveto{\pgfpoint{-.1mm/\slope}{-.1mm}}
\pgfpathlineto{\pgfpoint{1.1mm/\slope}{1.1mm}}
\pgfsetstrokecolor{\tikz@pattern@color}
\pgfusepath{stroke}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\fill[pattern=slant lines,pattern color=red] (0,0) rectangle (5,5);
\fill[pattern color=blue,pattern=slant lines,slope=0.3] (5,0) rectangle (10,5);
\end{tikzpicture}
\end{document}
答案2
在我的解决方案中,我附加了\def\patterncolor{#1}
原始pattern color
样式并将其添加到与的一起\patterncolor
的变量中并将其与一起使用。\pgfdeclarepatternformonly
\slope
\pgfsetstrokecolor{\patterncolor}
percusse 的回答使用基本相同的方法,但使用/tikz/pattern color
/的实际内部名称\tikz@pattern@color
,而我用 来伪造\patterncolor
。
代码
\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}
\tikzset{
slope/.store in=\slope,
% patternkolor/.store in=\patterncolor,% with the next line changed to:
% pattern color/.append style={patternkolor=#1}
pattern color/.append code={\def\patterncolor{#1}}
}
\newcommand{\theslope}{0.7}
\pgfdeclarepatternformonly{diagonal lines}
{\pgfpoint{-.1mm/\theslope}{-.1mm}}{\pgfpoint{1.1mm/\theslope}{1.1mm}}
{\pgfpoint{1mm/\theslope}{1mm}}
{
\pgfsetlinewidth{0.4pt}
\pgfpathmoveto{\pgfpoint{-.1mm/\theslope}{-.1mm}}
\pgfpathlineto{\pgfpoint{1.1mm/\theslope}{1.1mm}}
\pgfusepath{stroke}
}
\pgfdeclarepatternformonly[\slope,\patterncolor]{slant lines}
{\pgfpoint{-.1mm/\slope}{-.1mm}}{\pgfpoint{1.1mm/\slope}{1.1mm}}
{\pgfpoint{1mm/\slope}{1mm}}
{
\pgfsetlinewidth{0.4pt}
\pgfpathmoveto{\pgfpoint{-.1mm/\slope}{-.1mm}}
\pgfpathlineto{\pgfpoint{1.1mm/\slope}{1.1mm}}
\pgfsetstrokecolor{\patterncolor}
\pgfusepath{stroke}
}
\begin{document}
\begin{tikzpicture}
\draw[pattern=diagonal lines,pattern color=blue] (0,0) rectangle (5,5);
\tikzset{every path/.append style={xshift=6cm}}
\draw[pattern=slant lines, slope=0.7,pattern color=blue] (0,0) rectangle (5,5);
\end{tikzpicture}
\begin{tikzpicture}
\draw[pattern=slant lines, slope=0.7,pattern color=green] (0,0) rectangle (5,5);
\tikzset{every path/.append style={xshift=6cm}}
\draw[pattern=slant lines, slope=0.2,pattern color=green] (0,0) rectangle (5,5);
\end{tikzpicture}
\end{document}
输出