5

I am interested in producing a series of balls which contain a pictorical idea of movement, to represent a gas. As such, I would like to apply a rotation in each of this set of "balls in motions" (which I shall refer henceforth as just mballs) according to random angles.

My code so far looks like this

\documentclass{article}
\usepackage{tikz}
\usepackage{xcolor}
\usetikzlibrary{arrows,snakes,backgrounds}

%Colors%
\definecolor{Red}{rgb}{0.922526, 0.385626, 0.209179}


%Defs%
\def\ball at (#1,#2){\draw[fill=Red!30,Red!30] (#1,#2) circle (4pt);
\draw[fill=Red!50,Red!50] (#1,#2)+(.15cm,0) circle (4pt);
\draw[fill=Red!70,Red!70] (#1,#2)+(.3cm,0) circle (4pt);}

\begin{document}
\begin{tikzpicture} 
    \foreach \x in {-2,...,2}
        \foreach \y in {-2,...,2}
        {\ball at (\x,\y)}
\end{tikzpicture}
\end{document}

Which produces

enter image description here

I tried a couple of things so far, but my problem is, particularly, to let each of this mballs acquire a different angle. That is, the randomness of the angles is not a big deal, but if I try to add an angles in the loops, which could depend for example on the variables \x or \y it just doesn't work, I mean, I tried something like

    \foreach \x in {-2,...,2}
        \foreach \y in {-2,...,2}
        {[rotate=15*\x*\y]\ball at (\x,\y)}

or even for a fixed angle

    \foreach \x in {-2,...,2}
        \foreach \y in {-2,...,2}
        {[rotate=30]\ball at (\x,\y)}

or even for a fixed angle. So, to wrap up, my questions are:

(1) How should I adjust my syntax for this to work? That is, I'd like to still be able to perform the loop and apply a rotation to the mballs in each step.

(2) Not so important, but relevant, what's the best way to implement the randomness in such angle?

3
  • 2
    I'm not an expert, but I think your rotate=... should be inside your \draw options. Also, the manual mentions \pgfmathrandominteger{<macro>}{<min>}{<max>}, so if you add, say, \pgfmathrandominteger{\nice}{-20}{20} just before the \draws in your definition and then \draw[rotate=\nice,<more stuff>], you should have a randomized rotation.
    – user226564
    Dec 28, 2020 at 18:12
  • I've tried something among those lines; in this case I did add a rotate within each draw in \def, yet I didn't figure out how to apply the same rotation to each draw - note that each mball is built of 3 draw commands and therefore the random rotation should be the same for each of those parts. In this case, I'd like to know how to fix the syntax so that I can apply the rotation to the whole \def. Got it? Dec 28, 2020 at 18:55
  • 1
    What I'd do: \def\ball at (#1,#2){ \pgfmathrandominteger{\nice}{-20}{20} \draw[fill=Red!30,rotate=\nice] (#1,#2) circle (4pt); \draw[fill=Red!50,rotate=\nice] (#1,#2)+(.15cm,0) circle (4pt); \draw[fill=Red!70,rotate=\nice] (#1,#2)+(.3cm,0) circle (4pt);}
    – user226564
    Dec 28, 2020 at 19:00

1 Answer 1

8

Your choice of defining the command \ball the way you do it removes the possibility of easily passing optional arguments (as the rotation angle) to your construction.

This could be solved by rewriting the definition of your command. But tikZ/pgf provides a ready-made solution for your problem: pics.

From the manual:

The idea is that a pic is simply some code that you can add to a picture at different places using the pic command whose syntax is almost identical to the node command.

In your situation (I've adapted your code to my personal taste),

\tikzset{balls/.pic={
    \fill[Red!30] (-.15cm,0) circle (4pt);
    \fill[Red!50] (0,0) circle (4pt);
    \fill[Red!70] (.15cm,0) circle (4pt);}
}

inserted before your tikzpicture would allow you to insert a rotated version of the three balls anywhere:

\pic[rotate=10] at (3,2) {balls};

Now Jairo A. del Rio's comment is easy to implement:

\documentclass{article}
\usepackage{tikz}
%Colors%
\definecolor{Red}{rgb}{0.922526, 0.385626, 0.209179}

\tikzset{balls/.pic={
    \fill[Red!30] (-.15cm,0) circle (4pt);
    \fill[Red!50] (0,0) circle (4pt);
    \fill[Red!70] (.15cm,0) circle (4pt);}
}

\begin{document}

\begin{tikzpicture} 
    \foreach \x in {-2,...,2}
        \foreach \y in {-2,...,2}
        {\pgfmathsetmacro{\myangle}{360*rnd}
        \pic[rotate=\myangle] at (\x,\y) {balls};}
\end{tikzpicture}
\end{document}

enter image description here

3
  • This was exactly what I needed, I felt that my syntax was restricting such possibility, but got really boggled on how to change it. Thanks so much, this answer will help me (and hopefully others) in much broader context. Dec 28, 2020 at 23:01
  • @MarceloBroinizi Yes the pic mechanism is useful in many situations and is quite powerfull too (if, for instance, you wanted to change the color, you can define pics with parameters, etc.). Happy that helped. Dec 29, 2020 at 14:22
  • @MarceloBroinizi I just noticed I used the wrong multiplier for the random angle: should be 360 not 180 since rnd gives a random number between 0 and 1. Dec 29, 2020 at 14:23

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.