5 如何自定义tikz的填充图案

发布于 2022-05-13 11:35:03

现有如下代码:

\documentclass{ctexart}
\usepackage{tikz}
\usetikzlibrary{patterns.meta}
\usepackage{bbding}
\tikzdeclarepattern{name=hua,
  type=uncolored,
  bottom left={(-.1pt,-.1pt)},
  top right={(10.1pt,10.1pt)},
  tile size={(10pt,10pt)},
  tile transformation={rotate=-45},
  code={
\tikzset{x=1pt,y=1pt}
\node{\FourClowerOpen};
} }
\begin{document}
\begin{tikzpicture}
 \draw[pattern=hua](0,0)rectangle(4,4);
\end{tikzpicture}
\end{document}

我打算用bbding宏包的FourClowerOpen作为填充图案,编译报错说
node不能用于tikzdeclarepattern,请教各位大佬如何修改?

查看更多

关注者
0
被浏览
1.5k
雾月
雾月 2022-05-13
这家伙很懒,什么也没写!

patterns 无法做到这一点。可以使用 /tikz/path picture。这样可以使用任意内容填充,包括 tikz 绘图命令。

image.png

\documentclass{ctexart}
\usepackage{tikz}
\usepackage{bbding}

\makeatletter
\newlength\this@pgf@bop@width
\newlength\this@pgf@bop@height

\def\setboxaspattern#1#2{\expandafter\newbox\csname this@pgf@box@pattern#1\endcsname
  \expandafter\setbox\csname this@pgf@box@pattern#1\endcsname\hbox{#2}%
  \expandafter\edef\csname this@pgf@bop@#1@width\endcsname{\the\wd\csname this@pgf@box@pattern#1\endcsname}%
  \expandafter\edef\csname this@pgf@bop@#1@height\endcsname{\the\ht\csname this@pgf@box@pattern#1\endcsname}%
}
\tikzset{
  box as pattern/.code 2 args={%
    \expandafter\this@pgf@bop@width\csname this@pgf@bop@#2@width\endcsname
    \expandafter\this@pgf@bop@height\csname this@pgf@bop@#2@height\endcsname
    \pgfkeysalso{/tikz/path picture={%
      \pgf@process{\pgfpointanchor{path picture bounding box}{north east}}%
      \pgf@xa\pgf@x \pgf@ya\pgf@y
      \pgf@process{\pgfpointanchor{path picture bounding box}{south west}}%
      \pgf@xb\pgf@x \pgf@yb\pgf@y \pgf@yc\pgf@yb
      \pgfutil@loop
        {%
        \pgfutil@loop
          \expandafter\pgftext\expandafter[#1,at=\pgfqpoint{\pgf@xb}{\pgf@yb}]{\copy\csname this@pgf@box@pattern#2\endcsname}%
          \ifdim\pgf@yb<\pgf@ya
          \advance\pgf@yb\this@pgf@bop@height
        \pgfutil@repeat
        }%
        \ifdim\pgf@xb<\pgf@xa
        \advance\pgf@xb\this@pgf@bop@width
        \pgf@yb\pgf@yc
      \pgfutil@repeat
    }}%
  }
}
\makeatother

\setboxaspattern{hua}{\FourClowerOpen}
\setboxaspattern{huarotate}{\rotatebox{22.5}{\FourClowerOpen}}
\setboxaspattern{image}{\includegraphics[width=2cm,height=2cm]{example-image}}
\usetikzlibrary{graphs,graphs.standard}
\setboxaspattern{tikzfancy}{\tikz
  \graph [nodes={draw, circle, rotate=25}, clockwise, radius=.5cm,
    empty nodes, n=5] {
      subgraph I_n [name=inner] --[complete bipartite]
      subgraph I_n [name=outer]
    };}

\begin{document}

\begin{tikzpicture}
 \draw[box as pattern={left,base}{hua}](0,0)rectangle(4,4);
\end{tikzpicture}
\tikz\draw[box as pattern={left,top}{huarotate}](0,0)rectangle(4,4);

\tikz\draw[box as pattern={}{tikzfancy}](0,0)rectangle(10,10);

\tikz\draw[box as pattern={left,bottom}{image}](0,0)rectangle(10,4);
\end{document}

\setboxaspattern 第一个参数是 box pattern 名,第二个参数是内容。
box as pattern 的第一个参数是 \pgftext 可用的选项,第二个参数为预先定义的 box pattern 名。

可以做成在使用时声明,但为了一致性(pattern 均是先声明再使用),仍然做成声明和使用分离的。

参考:https://tex.stackexchange.com/questions/103980

实际上,这样使用会重复使用这些盒子,造成一定的浪费。理想情况下,对于这种重复的内容,应该仅存储一个,之后的内容引用这一个即可。但目前只有 pdftex(和 luatex 的 pdf 模式)能做到这一点,xetex 无法做到。
而 xetex 要支持这一点,则要等到 LaTeX 2022-06-01 这一版(也就是目前的 LaTeX-dev)或者使用 pdfmanagement-testphase

1 个回答

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览