1

I am trying again to recreate some strange images. I am trying to generate hexagons of nonstop with three colors. The distribution of these three should be

Color 1 = (N-1)^2
Color 2 = (N-1)*N
Color 3 = N^2

where N is the side length of the non stops. The result should look something like this.

enter image description here

NOTE: Here 4 colors is used, I only need 3! Secondly the distribution itself is wrong in the image above.

The idea is then to "sort" the nonstop to make the figure below

enter image description here

I am able to create the hexagonal non stop pattern (after a lot of work!), see below.

enter image description here

What I want to improve is this

  • How can I control exactly how many of each color type that is present in the hexagon. I still want them to appear randomly in the hexagon.
  • Any improvements in apperance to look a bit more like actual candy would be much appreciated.
  • Is there an easier approach to generating the hexagon? I had to do a lot of mathematics, and trial and error to get the result right. (Also why is there a small space between my rows?).

Any other approach to obtain the result is much appreciated.

Code

\documentclass[12pt]{article}
\usepackage{ifthen, tikz}
\pgfmathsetseed{\number\pdfrandomseed}

\usetikzlibrary{shapes.geometric}

\definecolor{maincolorMedium}{HTML}{425b9b}

\tikzset{
    nonstop/.style={
      circle,
      minimum size=10mm,
      inner sep=0mm,
      outer sep=0mm,
      rotate=0,
    draw
    }
}

\definecolor{nonstopRed}{HTML}{EB4F5C}
\definecolor{nonstopYellow}{HTML}{FFE103}
\definecolor{nonstopBlack}{HTML}{02031B}

\newcommand{\ballcolor}{none}

% Example: Pick color by ID
\newcommand{\incolor}{
    \pgfmathsetmacro{\rng}{int(random(1,3))}
    \ifthenelse{\rng < 2}{ \renewcommand{\ballcolor}{nonstopRed}}{%
    \ifthenelse{\rng < 3}{ \renewcommand{\ballcolor}{nonstopYellow} }{%
                           \renewcommand{\ballcolor}{nonstopBlack}
    }
    }
}

\newcommand{\createNonstop}[1]{%
\begin{tikzpicture}
\def\hexagonSize{#1}
\pgfmathsetmacro{\J}{2*\hexagonSize-1}
    \foreach \j in {1,...,\J} {
        \pgfmathsetmacro{\offset}{0.5*Mod(\j,2)}
        \ifthenelse{\j > \hexagonSize}
           {\pgfmathsetmacro{\hexLength}{\hexagonSize + \J - \j}
            \pgfmathsetmacro{\jIndent}{0.5*(\J - \j)}}
           {\pgfmathsetmacro{\hexLength}{\hexagonSize + \j-1}
            \pgfmathsetmacro{\jIndent}{0.5*(\j-1)}}
        \foreach \k in {1,...,\hexLength} {
        \incolor
            \node[nonstop,fill=\ballcolor] at (\k  -\jIndent,\j) {};
        }
    }
\end{tikzpicture}
}

\begin{document}

\createNonstop{2}

\createNonstop{3}

\createNonstop{4}

\createNonstop{5}

\end{document}
4

Sorry, my previous post did not include the requirement on the number of colors, which I corrected now. This code runs through a loop of 3*N*(N+1)+1 steps (note that my definition of N is your N+1) and then selects a random number between 1 and n_tot=3*N*(N+1)+1, between 1 and n_tot=3*N*(N+1) and so on, where in each step one color item gets taken out, hence the three counters none, ntwo and nthree. At each step none+ntwo+nthree=n_tot and the counter of each color pile gets reduced. This ensures that there will be (N+1)^2 smarties of the first color, N*(N+1) of the second color and N^2 of the last color. The lattice is just constructed layer by layer.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{shadows.blur}
\newcounter{none}
\newcounter{ntwo}
\newcounter{nthree}
\begin{document}
\begin{tikzpicture}[pics/hegrid/.style={code={
  \xdef\LstOne{""}
  \setcounter{none}{\the\numexpr(#1+1)*(#1+1)}
  \setcounter{ntwo}{\the\numexpr#1*(#1+1)}
  \setcounter{nthree}{\the\numexpr#1*#1}
  \pgfmathtruncatemacro{\Nm}{int(3*#1*(#1+1)+1)}
  \foreach \YY in {\Nm,\the\numexpr\Nm-1,...,1}
  {\pgfmathtruncatemacro{\itest}{random(1,\YY)}
  \ifnum\itest>\number\value{none}\relax
   \ifnum\itest>\the\numexpr\YY-\number\value{nthree}\relax
    \addtocounter{nthree}{-1}
    \pgfmathsetmacro{\mycol}{{\LstCols}[2]}
    \xdef\LstOne{\LstOne,"\mycol"}
   \else    
    \addtocounter{ntwo}{-1}
    \pgfmathsetmacro{\mycol}{{\LstCols}[1]}
    \xdef\LstOne{\LstOne,"\mycol"}
   \fi
  \else
   \addtocounter{none}{-1}
   \pgfmathsetmacro{\mycol}{{\LstCols}[0]}
   \xdef\LstOne{\LstOne,"\mycol"}
  \fi}
  \setcounter{none}{1}
  \path [/utils/exec=\pgfmathsetmacro{\mycol}{{\LstOne}[1]}]
  node[smartie=\mycol]{};
  \foreach \XX in {1,...,#1}
  {\foreach \YY [count=\NYY] in {0,...,5}
  {\path (\NYY*60:\XX) -- (\YY*60:\XX) foreach \ZZ in {1,...,\XX} 
  {\pgfextra{\stepcounter{none}%
  \pgfmathsetmacro{\mycol}{{\LstOne}[\number\value{none}]}}
  node[smartie=\mycol,pos={\ZZ/\XX}]{}};}}}},
  smartie/.style={circle,draw,inner sep=3mm,blur shadow,
  path picture={\shade[ball color=#1] (0.15,-0.15) circle[radius=9mm];}}]
 \edef\LstCols{"red","blue","green!70!black"}
 \path (0,0) pic{hegrid=1} (5,0) pic{hegrid=2}
 (2,-6) pic{hegrid=3};
\end{tikzpicture}
\end{document}

enter image description here

The ordered pattern is much easier to obtain.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{shadows.blur}
\begin{document}
\begin{tikzpicture}[pics/ordered hegrid/.style={code={
  \path [/utils/exec=\pgfmathsetmacro{\mycol}{{\LstCols}[0]}]
  node[smartie=\mycol]{};
  \foreach \XX in {1,...,#1}
  {\foreach \YY [count=\NYY] in {0,...,5}
  {\path (\NYY*60+60:\XX) -- (\YY*60+60:\XX) foreach \ZZ in {1,...,\XX} 
  {\pgfextra{%
  \pgfmathtruncatemacro{\myind}{ifthenelse(\NYY<3 || (\NYY==3 && \ZZ == \XX),0,ifthenelse(\NYY<5,1,2))}
  \pgfmathsetmacro{\mycol}{{\LstCols}[\myind]}}
  node[smartie=\mycol,pos={\ZZ/\XX}]{}};}}}},
  smartie/.style={circle,draw,inner sep=3mm,blur shadow,
  path picture={\shade[ball color=#1] (0.15,-0.15) circle[radius=9mm];}}]
 \edef\LstCols{"red","blue","green!70!black"}
 \path (0,0) pic{ordered hegrid=1} (5,0) pic{ordered hegrid=2}
 (2,-6) pic{ordered hegrid=3};
\end{tikzpicture}
\end{document}

enter image description here

  • 1
    Note to myself: mini-issue in the new option parse=true in foreach. – user121799 Jun 27 at 2:50
  • Wow! This looks amazing! Any idea how to also produce the sorted output image at the bottom? I tried to change your code, but alas it was outside my abilities. – N3buchadnezzar Jun 27 at 9:17
  • 1
    @N3buchadnezzar Oh sorry, I missed that, too. This one is much easier. – user121799 Jun 27 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.