13

I'm trying to reproduce this illustration of a high entropy alloy (HEA) in TikZ:

high entropy alloy illustration

What I have so far looks quite bland because I can't find a way to randomly assign one out of a list of colors.

TikZ black and white HEA

\documentclass[tikz]{standalone}

\def\colors{{red,green,blue,yellow}}

\begin{document} \begin{tikzpicture}[] \foreach \i in {1,...,12} { \foreach \j in {1,...,6} { \foreach \k in {1,...,4} { \pgfmathparse{rnd} \definecolor{randColor}{rgb}{\pgfmathresult,\pgfmathresult,\pgfmathresult} \shade[ball color=randColor] (\i, {0.5*\j+\k}) circle(0.4); } } } \end{tikzpicture} \end{document}

Two questions:

  • How can I assign one of \colors{{red,green,blue,yellow}} either randomly or seemingly randomly based on e.g. Mod(num, base) to each of the balls? I was unable to get array indexing to work:

    \shade[ball color=\colors[Mod(\i+\j+\k, 4)]
    

    and

    \pgfmathparse{\i+\j+\k}
    \shade[ball color=\colors[Mod(\pgfmathresult, 4)]]
    

    both throw errors.

  • Can the viewing angle be rotated so as to resemble the target image?

Janosh
  • 4,042

2 Answers2

9

I think the simplest way is to define your colors in a list with \pgfmathdeclarerandomlist and then you can randomly select an item using \pgfmathrandomitem. Since you have a 2D TikZ image, changing the view means to change the position (coordinates) of the balls.

enter image description here

Code:

\documentclass[tikz]{standalone}

\pgfmathdeclarerandomlist{colors}{% {red}% {green}% {blue}% {yellow}% }

\begin{document} \begin{tikzpicture}[] \foreach \i in {1,...,12} { \foreach \j in {1,...,6} { \foreach \k in {1,...,4} { \pgfmathrandomitem{\randColor}{colors} \shade[ball color=\randColor] (\i-\j/3, {0.5*\j+\k}) circle(0.4); } } } \end{tikzpicture} \end{document}

By the way, the answers to Drawing 3d crystal lattice with molecular layer in tikz show you other possibilities to build such a cube of "balls". These can be also randomly colored. For instance, for the answer of JLDiaz:

enter image description here

\documentclass{standalone}
\usepackage{tikz}

\usetikzlibrary{calc,fadings,decorations.pathreplacing}

\pgfmathdeclarerandomlist{colors}{% {red}% {green}% {blue}% {yellow}% }

\begin{document}

% You can tweak these \def\ballradius{0.45} %

\def\DrawRow#1#2{ \foreach \x in {0,...,#2} \pgfmathrandomitem{\randColor}{colors} \shade[ball color=\randColor] ($(#1) +(\x, 0,0)$) circle(\ballradius); } \def\DrawOddPlane#1{ \pgfmathsetmacro{\aux}{#1-1} \foreach \z in {0,...,#1} { \DrawRow{0,0,\z}{#1} \if\z#1\relax\else \DrawRow{0.5,0,\z+0.5}{\aux} \fi } } \def\DrawEvenPlane#1{ \pgfmathsetmacro{\aux}{#1-1} \foreach \z in {0,...,#1} { \DrawRow{0.5,0,\z}{\aux} \if\z#1\relax\else \DrawRow{0,0,\z+0.5}{#1} \fi } }

\begin{tikzpicture} \foreach \y in {0,...,3} { \begin{scope}[yshift=\y cm] \DrawOddPlane{3} \end{scope} \if\y3\relax\else \begin{scope}[yshift=\y cm + 0.5cm] \DrawEvenPlane{3} \end{scope} \fi } \pgfmathsetmacro{\cubex}{1} \pgfmathsetmacro{\cubey}{1} \pgfmathsetmacro{\cubez}{1} \draw (3,3,3) -- ++(-\cubex,0,0) -- ++(0,-\cubey,0) -- ++(\cubex,0,0) -- cycle; \draw (3,3,3) -- ++(0,0,-\cubez) -- ++(0,-\cubey,0) -- ++(0,0,\cubez) -- cycle; \draw (3,3,3) -- ++(-\cubex,0,0) -- ++(0,0,-\cubez) -- ++(\cubex,0,0) -- cycle; \end{tikzpicture} \end{document}

Ñako
  • 3,626
  • 1
    Cool! I'd never come across \pgfmathdeclarerandomlist and \ pgfmathrandomitem. Just what I needed. – Janosh Aug 28 '20 at 13:13
2

With the great help of @Ñako, here's the final result.

AlCoCrFeNi high entropy alloy

% Cartoon of the AlCoCrFeNi high entropy alloy (HEA) with body-centered cubic (BCC) lattice.

\documentclass[tikz]{standalone}

\pgfmathdeclarerandomlist{colors}{{red!80}{teal}{blue!80}{orange}{blue!20}}

\begin{document} \begin{tikzpicture} \foreach \i in {1,...,12} { \foreach \j in {1,...,4} { \foreach \k in {1,...,4} { \pgfmathrandomitem{\randColor}{colors} \shade[ball color=\randColor] (-\i+0.3\j, -0.2\j+1.2\k) circle(0.3); } \foreach \k in {1,...,3} { \pgfmathrandomitem{\randColor}{colors} \shade[ball color=\randColor] (-\i+0.5+0.3\j, -0.2\j+1.2\k+0.6) circle(0.3); } } } \foreach \el/\color [count=\n] in {Al/red!80, Co/blue!80, Cr/teal, Fe/orange, Ni/blue!20} { \shade[ball color=\color] (2, 5.5-\n) circle(0.3) node[right=1em] {\el}; } \end{tikzpicture} \end{document}

Janosh
  • 4,042