间谍中的 Tikz 图案大小

间谍中的 Tikz 图案大小

enter image description here

我在使用图案填充形状时遇到问题:

我有一个形状,其中填充了自定义图案(距离相同的简单点),我想放大该形状的一个角。我用 spy(放大倍数 = 10)执行此操作。现在在放大倍数内,点之间的距离与真实图片中的距离相同,但我希望它们也缩放。有人知道怎么做吗?谢谢帮助

\documentclass[10pt,a4paper]{article}
\usepackage[latin1]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{arrows, plotmarks, patterns, spy}
\usepackage{pgfplots}


\pgfdeclarepatternformonly{dots-wide}% name
{\pgfpointorigin}% bottom left
{\pgfqpoint{6mm}{6mm}}% top right
{\pgfqpoint{6mm}{6mm}}% tile size
{% code
    \pgfpathcircle{\pgfpoint{0.3mm}{0.3mm}}{0.3mm} \pgfusepath{fill}
    \pgfusepath{fill}
}

\begin{document}


\begin{tikzpicture}[spy using outlines={circle, magnification=10, connect spies, transform shape}]
    \draw[pattern=dots-wide] (0,0) rectangle (3,3);
    \spy[size=5cm] on (2,2) in node at (8,2);
\end{tikzpicture}
\end{document}

答案1

我不确定使用模式是否有一个优雅的答案。这是因为模式很快,但也存在某些缺陷。pgfmanual 在第 104.1 节中说:

使用模式时存在许多缺陷和限制。首先,一旦声明了模式,就不能再更改它。特别是,不可能放大它或更改线宽。这种灵活性要求模式的重复不是由图形语言完成的,而是在 pgf 级别完成的。这将使模式的生成和渲染速度慢几个数量级。

如果您想使用 spy,您可能只需要采用更传统(但也慢得多)的方法来绘制点。(有很多方法可以使其更优雅,例如使用path picture但这里我仅介绍一个相当笨拙的解决方法,将在下一个代码中显示。)在下文中,我列出了一些尝试,这些尝试表明模式不容易转换,并提供了第一个笨拙的解决方法。

\documentclass[10pt,a4paper]{article}
\usepackage[latin1]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{tikz}
\usetikzlibrary{arrows, plotmarks, patterns, spy}
% made the pattern a bit more flexible but am not using it
\pgfdeclarepatternformonly[\dotradius,\dotdistance]{dots-wide}% name
{\pgfpointorigin}% bottom left
{\pgfqpoint{\dotdistance}{\dotdistance}}% top right
{\pgfqpoint{\dotdistance}{\dotdistance}}% tile size
{% code
    \pgfpathcircle{\pgfpoint{\dotradius}{\dotradius}}{\dotradius} \pgfusepath{fill}
    \pgfusepath{fill}
}
\tikzset{
dot radius/.store in=\dotradius, 
dot radius=0.3mm,
dot distance/.store in=\dotdistance, 
dot distance=6mm
}

\newsavebox{\mybox}
\begin{document}

\section*{Resistance of patterns against transformations}

\begin{tikzpicture}[font=\sffamily]
 \pattern [pattern=bricks] (-1,-1) rectangle (1,1);
 \node[anchor=south] at (0,1.1) {original};
 \begin{scope}[xshift=3cm]
  \pattern [pattern=bricks,rotate=45] (-1,-1) rectangle (1,1);
  \node[anchor=south] at (0,1.4) {\verb|rotate=45|};
 \end{scope}
 % these weird shifts are necessary because transform canvas is rather brutal
 \begin{scope}[xshift={cos(45)*8cm},yshift=-{sin(45)*8cm},transform canvas={rotate=45}]
  \pattern [pattern=bricks] (-1,-1) rectangle (1,1);
  \node[anchor=south,rotate=-45] at (1,1) {\verb|transform canvas={rotate=45}|};
 \end{scope}
\end{tikzpicture}

\section*{Not even saveboxes help}

\begin{lrbox}{\mybox}%
\begin{tikzpicture}[font=\sffamily]
 \pattern [pattern=bricks] (-1,-1) rectangle (1,1);
\end{tikzpicture}%
\end{lrbox}

\begin{tikzpicture}[font=\sffamily]
 \node at (0,0){\usebox{\mybox}};
 \node[anchor=south] at (0,1.1) {original};
 \begin{scope}[xshift=3cm]
  \node[rotate=45] at (0,0){\usebox{\mybox}};
  \node[anchor=south] at (0,1.4) {\verb|rotate=45|};
 \end{scope}
 % these weird shifts are necessary because transform canvas is rather brutal
 \begin{scope}[xshift={cos(45)*8cm},yshift=-{sin(45)*8cm},transform canvas={rotate=45}]
  \node at (0,0){\usebox{\mybox}};
  \node[anchor=south,rotate=-45] at (1,1) {\verb|transform canvas={rotate=45}|};
 \end{scope}
\end{tikzpicture}

% \section*{Resistance of patterns against transformations}
% 
% \begin{tikzpicture}[font=\sffamily]
%  \pattern [pattern=dots-wide] (-1,-1) rectangle (1,1);
%  \node[anchor=south] at (0,1.1) {original};
%  \begin{scope}[xshift=3cm]
%   \pattern [pattern=dots-wide,rotate=45] (-1,-1) rectangle (1,1);
%   \node[anchor=south] at (0,1.4) {\verb|rotate=45|};
%  \end{scope}
%  % these weird shifts are necessary because transform canvas is rather brutal
%  \begin{scope}[xshift={cos(45)*8cm},yshift=-{sin(45)*8cm},transform canvas={rotate=45}]
%   \pattern [pattern=dots-wide] (-1,-1) rectangle (1,1);
%   \node[anchor=south,rotate=-45] at (1,1) {\verb|transform canvas={rotate=45}|};
%  \end{scope}
% \end{tikzpicture}
% 
% \section*{Not even saveboxes help}
% 
% \begin{lrbox}{\mybox}%
% \begin{tikzpicture}[font=\sffamily]
%  \pattern [pattern=dots-wide] (-1,-1) rectangle (1,1);
% \end{tikzpicture}%
% \end{lrbox}
% 
% \begin{tikzpicture}[font=\sffamily]
%  \node at (0,0){\usebox{\mybox}};
%  \node[anchor=south] at (0,1.1) {original};
%  \begin{scope}[xshift=3cm]
%   \node[rotate=45] at (0,0){\usebox{\mybox}};
%   \node[anchor=south] at (0,1.4) {\verb|rotate=45|};
%  \end{scope}
%  % these weird shifts are necessary because transform canvas is rather brutal
%  \begin{scope}[xshift={cos(45)*8cm},yshift=-{sin(45)*8cm},transform canvas={rotate=45}]
%   \node at (0,0){\usebox{\mybox}};
%   \node[anchor=south,rotate=-45] at (1,1) {\verb|transform canvas={rotate=45}|};
%  \end{scope}
% \end{tikzpicture}

\section*{A workaround}

\begin{tikzpicture}[spy using outlines={circle, magnification=10, connect spies, transform shape}]
    \draw (0,0) rectangle (3,3);
    \foreach \X in {0.3,0.9,...,2.7}
     {\foreach \Y in {0.3,0.9,...,2.7}
      {
      \fill (\X,\Y) circle (0.3mm);
      }}
    \spy[size=5cm] on (2,2) in node at (8,2);
\end{tikzpicture}
\end{document}

enter image description here

当然,使用 可以使其更加优雅path pictures。我认为人们可以通过这种方式重做任何装饰。可以说,使用该语法甚至更简单,但必须付出的代价是性能。另一方面,定义图案的起源更为直接。这样做的另一个优点是它可以用于 3D 投影。(我希望我在创建时就知道这个解决方法... ;-) (编辑\pgfextra:知道了可以剥离具有该功能的单元后,就摆脱了危险scalar。)

\documentclass{article}
\usepackage{tikz}

\usetikzlibrary{spy,calc}
% these parameters can be adusted
\tikzset{
dot radius/.store in=\dotradius, 
dot radius=0.3mm,
dot distance/.store in=\dotdistance, 
dot distance=6mm
}

\tikzset{dot pattern/.style={path picture={
\fill let \p1=($(path picture bounding box.north east)-(path picture bounding
box.south west)$), \n1={int(scalar(\x1/\dotdistance)))},
\n2={int(scalar(\y1/\dotdistance))} in
foreach \DotX in {1,...,\n1}
 {foreach \DotY in {1,...,\n2}
 {($(path picture bounding box.south west)+({(\DotX-1/2)*\dotdistance},
 {(\DotY-1/2)*\dotdistance})$) circle (\dotradius)}
};}}}

\begin{document}
\section*{A slightly more elegant version of the workaround}

\begin{tikzpicture}[spy using outlines={circle, magnification=10, connect spies, transform shape}]
    \draw[dot pattern] (0,0) rectangle (3,3);
    \spy[size=5cm] on (2,2) in node at (8,2);
\end{tikzpicture}

\begin{tikzpicture}[spy using outlines={circle, magnification=10, connect spies, transform shape}]
    \draw[dot pattern] plot[smooth cycle] coordinates {(0,0) (1,2) (3,3) (3,0)
    (2,-1)};
    \spy[size=5cm] on (2,1.5) in node at (8,2);
\end{tikzpicture}

\end{document}

enter image description here

另一种解决方法如下:创建模式的 pdf,然后使用它(例如,使用 clip)。然后,您可以放大而不需要 foreach 循环。确保启用外部化,例如通过使用 进行编译pdflatex -shell-escape

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize 

\usetikzlibrary{arrows, plotmarks, patterns, spy,external}
% made the pattern a bit more flexible but am not using the flexibility here
\pgfdeclarepatternformonly[\dotradius,\dotdistance]{dots-wide}% name
{\pgfpointorigin}% bottom left
{\pgfqpoint{\dotdistance}{\dotdistance}}% top right
{\pgfqpoint{\dotdistance}{\dotdistance}}% tile size
{% code
    \pgfpathcircle{\pgfpoint{\dotradius}{\dotradius}}{\dotradius} \pgfusepath{fill}
    \pgfusepath{fill}
}
\tikzset{
dot radius/.store in=\dotradius, 
dot radius=0.3mm,
dot distance/.store in=\dotdistance, 
dot distance=6mm
}

\newsavebox{\mybox}
\tikzexternalize

\begin{document}
% this is a trick to create some graphics without adding it to the document
% this trick is inspired by https://tex.stackexchange.com/a/433461/121799
\begin{lrbox}{\mybox}
\tikzsetnextfilename{mypattern}
\begin{tikzpicture}
  \fill [pattern=dots-wide] (-10,-10) rectangle (10,10);
\end{tikzpicture}
\end{lrbox}
\tikzexternaldisable
\section*{Another workaround}

\begin{tikzpicture}[spy using outlines={circle, magnification=10, connect spies, transform shape}]
    \begin{scope}
    \draw[clip] (0,0) rectangle (3,3);
     \node at (0,0) {\includegraphics{mypattern.pdf}};
    \end{scope}
    \spy[size=5cm] on (2,2) in node at (8,2);
\end{tikzpicture}
\end{document}

enter image description here

相关内容