Let's argue that I want to draw variations of the infinity symbol (Mostly because I can't draw ducks although it makes for a good MWE). I can't find a simple example that uses pgf/tikz keys to manipulate how a tikz pic is drawn in a concise manner. Looking over my own code base it looks like I'm rather confused about the topic myself.
Requirements :
Let's allow the size of the shape to be altered by the keys width
and height
and enable some wobble in the lobes with the keys inner target
and outer target
. Most importantly we want to select between various calligraphic pens, which must be set by code. This is controlled by selecting left
and 'right' for the pen
.
Code :
For this example you will need the spath
and calligraphy
style files, available here, available as the spath3
package and tikz calligraphy
libraries.
\documentclass[tikz]{standalone}
\usepackage{spath}
\usepackage{calligraphy}
\usetikzlibrary{calc}
\makeatletter
\tikzset{
infinity/.is family,
infinity/.pic = {
% This is the curve we wish to have drawn
\calligraphy let \p1=(0,0) in
(\p1) .. controls (-\infty@upper*\infty@width, \infty@height) and (-\infty@lower*\infty@width,-\infty@height) ..
(\p1) .. controls ( \infty@lower*\infty@width, \infty@height) and ( \infty@upper*\infty@width,-\infty@height) .. cycle;;
% This curve is simply here as a backup
\draw[line width=0.1, blue] let \p1=(0,0) in
(\p1) .. controls (-\infty@upper*\infty@width, \infty@height) and (-\infty@lower*\infty@width,-\infty@height) ..
(\p1) .. controls ( \infty@lower*\infty@width, \infty@height) and ( \infty@upper*\infty@width,-\infty@height) .. cycle;;
},
infinity,
pen/.is choice,
pen/left/.code={\pen (-.01,.01) -- (.01,-.01);},
pen/right/.code={\pen (-.01,-.01) -- (.01,.01);},
pen/.default=left,
pen/.initial=left,
width/.store in=\infty@width,
height/.store in=\infty@height,
inner target/.store in=\infty@upper,
outer target/.store in=\infty@lower,
}
\tikzset{
infinity,
width = 1 em,
height = 1 em,
inner target = 0.2 em,
outer target = 0.8 em,
}
%\tikzset{ % Fails to set the properties before the infinity/.code is executed.
% infinity/.style={width=1em, height=1em, inner target =0.2, outer target =0.8},
%}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw pic {infinity};
\end{tikzpicture}
\begin{tikzpicture}
\draw pic[infinity/pen=left] {infinity};
\end{tikzpicture}
\end{document}
Overview
I am trying to structure the code as follows. Group everything under the infinity
family. infinity
also acts as the tikz pic whose geometry is controlled by the dimensions \infty@DIMENSION
, where DIMENSION
is one of width
and height
, controlling the size, and upper
and lower
, controlling the wobble. The pen
is selected as described above.
Question(s) :
How does one set the defaults for the pic setting ? Setting the geometry keys in
infinity/.style
fails for me. I've therefore defined them the second\tikzset{}
call so that the MWE compiles out of the box.I also have to explicitly set the value pen for the calligraphic curve to display. Shouldn't this also be made part of the
infinity/.style
?This point relates to 1 and 2 above. Setting the dimensions under
infinity/.style
fails, as it does not set any of the dimensions beforeinfinity/.code
is executed.\tikzset{ infinity/.style={...}, }
In some other code I have I use the
DIMENISON/.get
handler instead of 'DIMENSION/.store in' handler. Should I be doing this here ?In the second
tikzpicture
environment I explicitly set pen usinginfinity/pen=...
is there a way I could simply writepen=...
? Is it then also necessary to specifyinfinity/.search also=/tikz/
in the first\tikzset
where I defineinfinity
?
Background :
There was a very good answer by Ryan Reich regarding some of this stuff but I can't find it now. I have read through the pgfkeys section of the pgfmanual, to me it reads more like an API document and I find I need an example to connect the dots, hence this question.
Update :
My original intention with this question has been userped by a package update, which is really nice in a "Oh darn" kind of way.