Created
January 30, 2024 08:22
-
-
Save jcboyd/7f4a2a2a6414c645ebe50fb132e1c81f to your computer and use it in GitHub Desktop.
Sieve of Eratosthenes with tikz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
\documentclass[tikz]{standalone} | |
\usepackage{tikz} | |
\begin{document} | |
\def\primes{2,3,5,7,11,13,17,19,23} | |
\def\revprimes{23,19,17,13,11,7,5,3,2} | |
\def\palette{{ | |
"0.00 0.00 1.00", | |
"0.00 0.00 1.00", | |
"0.00 0.00 1.00", | |
"0.00 0.00 1.00", | |
"0.00 0.00 1.00", | |
"0.00 0.00 1.00", | |
"0.00 0.00 1.00", | |
"0.73 0.00 0.00", | |
"1.00 0.98 0.00", | |
"0.00 0.77 1.00"}} | |
\def\width{5} | |
\def\height{5} | |
\newcommand{\drawboundingbox}[3]{% anchor, fill | |
\draw [thick, #3, fill=#2, fill opacity=0.2] (#1.north west) -- (#1.south west) -| (#1.north east) -- (#1.north west); | |
} | |
% for the ifnodedefined macro, full credit to: https://tex.stackexchange.com/questions/85528/checking-whether-or-not-a-node-has-been-previously-defined | |
\makeatletter | |
\long\def\ifnodedefined#1#2#3{% | |
\@ifundefined{pgf@sh@ns@#1}{#3}{#2}% | |
} | |
\makeatother | |
\foreach \prime [count=\pp] in \primes{ | |
\pgfmathtruncatemacro{\firststep}{\prime} | |
\pgfmathtruncatemacro{\secondstep}{\prime*\prime} | |
\pgfmathtruncatemacro{\thirdstep}{\secondstep+\prime} | |
\pgfmathtruncatemacro{\numgrid}{\width*\height} | |
\foreach \step in {1, \firststep, \secondstep, \thirdstep, ..., \numgrid}{ | |
\begin{tikzpicture} | |
% set canvas size | |
\useasboundingbox (0pt,0pt) rectangle (230pt,230pt); | |
% draw grid | |
\pgfmathtruncatemacro{\gridwidth}{\width} | |
\foreach \x [count=\xx] in {1, ..., \gridwidth} { | |
\pgfmathtruncatemacro{\gridheight}{\height-1} | |
\foreach \y [count=\yy] in {\gridheight, ..., 0} { | |
\pgfmathtruncatemacro{\cell}{\width*\y+\x} % draw location | |
\ifnum\cell>1 | |
\foreach \iterprime [count=\x] in \revprimes { | |
% define colour | |
\pgfmathparse{\palette[\x]} | |
\definecolor{fillcolour}{rgb}{\pgfmathresult}; | |
\ifnum\prime<\iterprime | |
\else % i.e. iterprime <= prime | |
\pgfmathparse{Mod(\cell,\iterprime)==0?1:0} | |
\ifnum\pgfmathresult>0 | |
\ifnum\iterprime=\prime % current prime--wait for grid | |
\ifnum\cell>\step | |
\else % label <= step | |
\ifnum\cell<\secondstep % skip over multiples between prime and prime**2 | |
\ifnum\cell>\firststep | |
\else | |
\ifnum\cell=\firststep | |
\node[inner sep=8pt, text=black, font=\bfseries, minimum size=1.2cm] (n\xx\yy) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell}; | |
\drawboundingbox{n\xx\yy}{fillcolour}{very thick}%{0.4} | |
\breakforeach | |
\else | |
% draw | |
\node[inner sep=8pt, minimum size=1.2cm] (n\xx\yy) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell}; | |
\drawboundingbox{n\xx\yy}{fillcolour}{semithick}%{0.2} | |
\breakforeach | |
\fi | |
\fi | |
\else | |
\node[inner sep=8pt, minimum size=1.2cm] (n\xx\yy) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell}; | |
\drawboundingbox{n\xx\yy}{fillcolour}{semithick}%{0.2} | |
\breakforeach | |
\fi | |
\fi | |
\else | |
\pgfmathtruncatemacro{\iterfirststep}{\iterprime} | |
\pgfmathtruncatemacro{\itersecondstep}{\iterprime*\iterprime} | |
\ifnum\cell<\itersecondstep % skip over multiples between prime and prime**2 | |
\ifnum\cell>\iterfirststep | |
\else | |
\ifnum\cell=\iterfirststep | |
\node[inner sep=8pt, text=black, font=\bfseries, minimum size=1.2cm] (n\xx\yy) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell}; | |
\drawboundingbox{n\xx\yy}{fillcolour}{very thick}%{0.4} | |
\breakforeach | |
\else | |
% draw | |
\node[inner sep=8pt, minimum size=1.2cm] (n\xx\yy) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell}; | |
\drawboundingbox{n\xx\yy}{fillcolour}{semithick}%{0.2} | |
\breakforeach | |
\fi | |
\fi | |
\else | |
\node[inner sep=8pt, minimum size=1.2cm] (n\xx\yy) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell}; | |
\drawboundingbox{n\xx\yy}{fillcolour}{semithick}%{0.2} | |
\breakforeach | |
% draw | |
\fi | |
\fi | |
\fi | |
\fi | |
} | |
\ifnodedefined{n\xx\yy}{} {% if node not drawn by a prime | |
\node[inner sep=8pt, minimum size=1.2cm] (char) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell}; | |
\drawboundingbox{char}{gray}{semithick}{0.2} | |
} | |
\fi | |
} | |
} | |
% \xdef\primelist{Primes:} | |
% \foreach \x in \primes{ | |
% \ifnum\x>\prime | |
% \else | |
% \ifnum\x=\prime | |
% \ifnum\step>1 | |
% \xdef\primelist{\primelist \ \ \x} | |
% \fi | |
% \else | |
% \xdef\primelist{\primelist \ \ \x} | |
% \fi | |
% \fi | |
% } | |
% \node[inner sep=8pt, anchor=west] (list) at (0.3, 9) {\Large\primelist}; | |
\end{tikzpicture} | |
\ifnum\step=\firststep | |
\ifnum\secondstep>\numgrid % break if overstep grid size (larger primes) | |
\breakforeach | |
\fi | |
\fi | |
\ifnum\step=\secondstep | |
\ifnum\thirdstep>\numgrid % break if overstep grid size (larger primes) | |
\breakforeach | |
\fi | |
\fi | |
} | |
} | |
\end{document} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment