Quantcast
Viewing all articles
Browse latest Browse all 2

Answer by user121799 for Tikz pattern size in spy

I am not sure there is an elegant answer using patterns. This is because patterns are fast, but have certain pitfalls. The pgfmanual says in section 104.1:

There are a number of pitfalls and restrictions when using patterns. First, once a pattern has been declared, you cannot change it anymore. In particular, it is not possible to enlarge it or change the line width. Such flexibility would require that the repeating of the pattern were not done by the graphic language, but on the pgf level. This would make patterns orders of magnitude slower to produce and to render.

If you want to use spy, you may just resort to more conventional (but also much slower) methods to draw the dots. (There are many ways to make this more elegant, e.g. using a path picture, but here I just present a rather clumsy workaround which will be shown in the next code.) In what follows I list some attempts that show that patterns are not transformed easily, and provide a first clumsy workaround.

\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}

Image may be NSFW.
Clik here to view.
enter image description here

This may, of course, be made much more elegant using path pictures. I think one can redo any decoration that way. Arguably, it is even simpler to use that syntax, but the price one has to pay is performance. On the other hand, it is more straightforward to define the origin of the pattern. Another advantage of this is that it can be used in 3D projections. (I wish I would have known about this workaround when I created this... ;-) (EDIT: Got rid of the dangerous \pgfextra after learning that one can strip off the units with the function 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 boundingbox.south west)$), \n1={int(scalar(\x1/\dotdistance)))},\n2={int(scalar(\y1/\dotdistance))} inforeach \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}

Image may be NSFW.
Clik here to view.
enter image description here

Another workaround works as follows: create a pdf of pattern, and use it (with clip, say). Then you can zoom in without the need of a foreach loop. Make sure that you enable the externalization, e.g. by compiling with 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}

Image may be NSFW.
Clik here to view.
enter image description here


Viewing all articles
Browse latest Browse all 2

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>