7

I can draw a coded reglet with the binary code, the Gray code or any other code from the code table.

enter image description here

\documentclass[border=7pt,10pt]{standalone}  
\usepackage{tikz,ifthen}
\usetikzlibrary{ positioning,calc }

\begin{document}

\begin{tikzpicture}

\foreach \cc [count=\ci]  in { 
{0 , 0 , 0 , 0},
{0 , 0 , 0 , 1},
{0 , 0 , 1 , 0},
{0 , 0 , 1 , 1},
{0 , 1 , 0 , 0}, 
{0 , 1 , 0 , 1},
{0 , 1 , 1 , 0},
{0 , 1 , 1 , 1},
{1 , 0 , 0 , 0},
{1 , 0 , 0 , 1},
{1 , 0 , 1 , 0},
{1 , 0 , 1 , 1},
{1 , 1 , 0 , 0},
{1 , 1 , 0 , 1},
{1 , 1 , 1, 0},
{1 , 1 , 1, 1}%
 }{
\foreach \nn [count=\ni] in \cc {
\ifthenelse{\nn>0}
{\def\mycol{red}}
{\def\mycol{white}}
\node[below right= \ni em and \ci em,fill=\mycol,inner sep=0,minimum size=1em,draw](n-\ci-\ni){ };
}
\pgfmathsetmacro{\NN}{int(\ci-1)}
\node[below=0em of n-\ci-4]{\footnotesize \NN};
}

\end{tikzpicture}

\begin{tikzpicture}

\foreach \cc [count=\ci]  in { 
{0 , 0 , 0 , 0},
{0 , 0 , 0 , 1},
{0 , 0 , 1 , 1},
{0 , 0 , 1 , 0},
{0 , 1 , 1 , 0},
{0 , 1 , 1 , 1},
{0 , 1 , 0 , 1},
{0 , 1 , 0 , 0}, 
{1 , 1 , 0 , 0},
{1 , 1 , 0 , 1},
{1 , 1 , 1, 1},
{1 , 1 , 1, 0},
{1 , 0 , 1 , 0},
{1 , 0 , 1 , 1},
{1 , 0 , 0 , 1},
{1 , 0 , 0 , 0}%
 }{
\foreach \nn [count=\ni] in \cc {
\ifthenelse{\nn>0}
{\def\mycol{red}}
{\def\mycol{white}}
\node[below right= \ni em and \ci em,fill=\mycol,inner sep=0,minimum size=1em,draw](n-\ci-\ni){ };
}
\pgfmathsetmacro{\NN}{int(\ci-1)}
\node[below=0em of n-\ci-4]{\footnotesize \NN};
}


\end{tikzpicture}

\end{document}

I would like to be able to do the same thing to draw an optical disk with either the Gray code or the binary code (like the ones below) but I get lost in the loops.

enter image description here

enter image description here

rpapa
  • 12,350

1 Answers1

7

UPDATE: Linear realization.

\documentclass[border=7pt,10pt]{standalone}  
\usepackage{tikz,ifthen}
\usetikzlibrary{positioning,calc}
\begin{document}

\pgfmathsetmacro{\Rmin}{1.2}
\pgfmathsetmacro{\DeltaR}{0.5}
\pgfmathsetmacro{\StartAng}{180}
\xdef\Lst{ 
{0 , 0 , 0 , 0},
{0 , 0 , 0 , 1},
{0 , 0 , 1 , 0},
{0 , 0 , 1 , 1},
{0 , 1 , 0 , 0}, 
{0 , 1 , 0 , 1},
{0 , 1 , 1 , 0},
{0 , 1 , 1 , 1},
{1 , 0 , 0 , 0},
{1 , 0 , 0 , 1},
{1 , 0 , 1 , 0},
{1 , 0 , 1 , 1},
{1 , 1 , 0 , 0},
{1 , 1 , 0 , 1},
{1 , 1 , 1, 0},
{1 , 1 , 1, 1}%
}
\begin{tikzpicture}
% first count the number of elements
\foreach \cc [count=\ci]  in \Lst {\xdef\Ntot{\ci}}
% now draw
\foreach \cc [count=\ci]  in \Lst {
\foreach \nn [count=\ni] in \cc {
\ifthenelse{\nn>0} % since you are working with integers, you could also
{\def\mycol{red}}  % use \ifnum here
{\def\mycol{white}} % which would spare you from loading ifthenelse
\draw[fill=\mycol] (\StartAng+\ci*360/\Ntot:\Rmin+\ni*\DeltaR) 
arc(\StartAng+\ci*360/\Ntot:{\StartAng+(\ci+1)*360/\Ntot}:\Rmin+\ni*\DeltaR)
-- ({\StartAng+(\ci+1)*360/\Ntot}:{\Rmin+(\ni+1)*\DeltaR}) 
arc({\StartAng+(\ci+1)*360/\Ntot}:\StartAng+\ci*360/\Ntot:{\Rmin+(\ni+1)*\DeltaR}) -- cycle;
\ifnum \ci=1
 \pgfmathtruncatemacro{\Ni}{\ni-1}
 \node[font=\small] at ({\StartAng+(\ci+0.5)*360/\Ntot}:{\Rmin+(\ni+0.5)*\DeltaR})
 {\Ni};
\fi
\pgfmathsetmacro{\Rmax}{\Rmin+\ni*\DeltaR+\DeltaR}
\xdef\Rmax{\Rmax}
}
\pgfmathsetmacro{\NN}{int(\ci-1)}
\node[anchor={\StartAng+180+(\ci+0.5)*360/\Ntot}] at ({\StartAng+(\ci+0.5)*360/\Ntot}:\Rmax){\footnotesize \NN};
}
\end{tikzpicture}

\xdef\Lst{{0 , 0 , 0 , 0},
{0 , 0 , 0 , 1},
{0 , 0 , 1 , 1},
{0 , 0 , 1 , 0},
{0 , 1 , 1 , 0},
{0 , 1 , 1 , 1},
{0 , 1 , 0 , 1},
{0 , 1 , 0 , 0}, 
{1 , 1 , 0 , 0},
{1 , 1 , 0 , 1},
{1 , 1 , 1, 1},
{1 , 1 , 1, 0},
{1 , 0 , 1 , 0},
{1 , 0 , 1 , 1},
{1 , 0 , 0 , 1},
{1 , 0 , 0 , 0}%
}
\begin{tikzpicture}
% first count the number of elements
\foreach \cc [count=\ci]  in \Lst {\xdef\Ntot{\ci}}
% now draw
\foreach \cc [count=\ci]  in \Lst {
\foreach \nn [count=\ni] in \cc {
\ifthenelse{\nn>0} % since you are working with integers, you could also
{\def\mycol{red}}  % use \ifnum here
{\def\mycol{white}} % which would spare you from loading ifthenelse
\draw[fill=\mycol] (\StartAng+\ci*360/\Ntot:\Rmin+\ni*\DeltaR) 
arc(\StartAng+\ci*360/\Ntot:{\StartAng+(\ci+1)*360/\Ntot}:\Rmin+\ni*\DeltaR)
-- ({\StartAng+(\ci+1)*360/\Ntot}:{\Rmin+(\ni+1)*\DeltaR}) 
arc({\StartAng+(\ci+1)*360/\Ntot}:\StartAng+\ci*360/\Ntot:{\Rmin+(\ni+1)*\DeltaR}) -- cycle;
\ifnum \ci=1
 \pgfmathtruncatemacro{\Ni}{\ni-1}
 \node[font=\small] at ({\StartAng+(\ci+0.5)*360/\Ntot}:{\Rmin+(\ni+0.5)*\DeltaR})
 {\Ni};
\fi
\pgfmathsetmacro{\Rmax}{\Rmin+\ni*\DeltaR+\DeltaR}
\xdef\Rmax{\Rmax}
}
\pgfmathsetmacro{\NN}{int(\ci-1)}
\node[anchor={\StartAng+180+(\ci+0.5)*360/\Ntot}] at ({\StartAng+(\ci+0.5)*360/\Ntot}:\Rmax){\footnotesize \NN};
}
\end{tikzpicture}
\end{document}

enter image description here

Of course, you could turn this into a macro that processes the list. Please let me know if you have problems doing that.

ORIGINAL ANSWER: I do not blame you at all if you do not take this answer seriously because it is just for fun. (Given that, it works surprisingly well, I'd say. ;-) EDIT: Fixed the sizes in radial directions.

\documentclass[border=7pt,10pt]{standalone}  
\usepackage{tikz,ifthen}
\usetikzlibrary{positioning,calc}
\usepgfmodule{nonlineartransformations}

\makeatletter
% from https://tex.stackexchange.com/a/434247/121799
\tikzdeclarecoordinatesystem{polar}{
    \tikz@scan@one@point\relax(#1)
    \polartransformation
}
% from the pgfmanual
\def\polartransformation{% from the pgfmanual section 103.4.2
\pgfmathsincos@{\pgf@sys@tonumber\pgf@x}%
\pgf@x=\pgfmathresultx\pgf@y% 
\pgf@y=\pgfmathresulty\pgf@y%
} % note: the following should work with arbitrary (nonlinear) transformations
\makeatother
\begin{document}

\begin{tikzpicture}
\begin{scope}[transform shape nonlinear=true]
\pgftransformnonlinear{\polartransformation}
\foreach \cc [count=\ci]  in { 
{0 , 0 , 0 , 0},
{0 , 0 , 0 , 1},
{0 , 0 , 1 , 0},
{0 , 0 , 1 , 1},
{0 , 1 , 0 , 0}, 
{0 , 1 , 0 , 1},
{0 , 1 , 1 , 0},
{0 , 1 , 1 , 1},
{1 , 0 , 0 , 0},
{1 , 0 , 0 , 1},
{1 , 0 , 1 , 0},
{1 , 0 , 1 , 1},
{1 , 1 , 0 , 0},
{1 , 1 , 0 , 1},
{1 , 1 , 1, 0},
{1 , 1 , 1, 1}%
 }{
\foreach \nn [count=\ni] in \cc {
\ifthenelse{\nn>0}
{\def\mycol{red}}
{\def\mycol{white}}
\node[below right= \ni em and 2.25*\ci em,fill=\mycol,inner sep=0,minimum
width=2.25em,minimum height=1em,draw](n-\ci-\ni){ };
}
\pgfmathsetmacro{\NN}{int(\ci-1)}
\node[below=0em of n-\ci-4]{\footnotesize \NN};
}
\end{scope}
\end{tikzpicture}

\begin{tikzpicture}
\begin{scope}[transform shape nonlinear=true]
\pgftransformnonlinear{\polartransformation}
\foreach \cc [count=\ci]  in { 
{0 , 0 , 0 , 0},
{0 , 0 , 0 , 1},
{0 , 0 , 1 , 1},
{0 , 0 , 1 , 0},
{0 , 1 , 1 , 0},
{0 , 1 , 1 , 1},
{0 , 1 , 0 , 1},
{0 , 1 , 0 , 0}, 
{1 , 1 , 0 , 0},
{1 , 1 , 0 , 1},
{1 , 1 , 1, 1},
{1 , 1 , 1, 0},
{1 , 0 , 1 , 0},
{1 , 0 , 1 , 1},
{1 , 0 , 0 , 1},
{1 , 0 , 0 , 0}%
 }{
\foreach \nn [count=\ni] in \cc {
\ifthenelse{\nn>0}
{\def\mycol{red}}
{\def\mycol{white}}
\node[below right= \ni em and 2.25*\ci em,fill=\mycol,inner sep=0,minimum
width=2.25em,minimum height=1em,draw](n-\ci-\ni){ };
}
\pgfmathsetmacro{\NN}{int(\ci-1)}
\node[below=0em of n-\ci-4]{\footnotesize \NN};
}
\end{scope}
\end{tikzpicture}

\end{document}

enter image description here

  • Thank you @marmot as always! I will use your first answer (I could more easily understand it later!) But I find the idea of nonlinear transformations excellent, I had not used it yet! – rpapa Aug 30 '18 at 06:43
  • 1
    @marmot Very very nice, especially the nonlinear transformation! One small thing (as I always seem to have something to nag about): You could determine \mycol as evaluate=\nn as \mycol using {ifthenelse(\nn,"red","white")} inside the \foreach options. Then you won't need the ifthen package, even if the list contains trailing decimals. – Max Aug 30 '18 at 06:56
  • The question that could follow would be, how to generate the binary list from a simple digital list? – rpapa Aug 30 '18 at 07:02
  • @rpapa Sorry, I do not understand this. How would the digital list look like? –  Aug 30 '18 at 09:39
  • @marmot : décimal to binary 1->0001, 2 -> 0010... – rpapa Aug 30 '18 at 18:17
  • @rpapa TikZ comes with bin, see p.936 of the pgfmanual. You can then access the digits with xstring methods, I think. There are also methods to add leading zeros, see e.g. here. That is, take a number, convert it to a binary with bin, add leading zeros, and then access the digits with xstring methods is the way I would go. Could of course well be that this is already done somewhere. –  Aug 30 '18 at 18:29