7

This question is similar to this question tikz: Distribute evenly and randomly circles (which is also where I got some of the code for this TiKz picture) but is different. I wish to draw multiple circles that do not overlap but some of these circles are different. Currently this is my code:

\documentclass{article}
\usepackage{tikz}
\usepackage[margin=0.5in]{geometry}
\newcommand{\fillrandomly}[5]{
    \xdef\xlist{4}
    \xdef\ylist{4}
    \pgfmathsetmacro\diametersqr{(#3*2)^2}
    \foreach \i in {1,...,#4}{
        \foreach \k in {1,...,20}{
            \pgfmathsetmacro\x{rnd*#1}
            \pgfmathsetmacro\y{rnd*#2}
            \xdef\collision{0}
            \foreach \element [count=\i] in \xlist{
                \pgfmathtruncatemacro\j{\i-1}
                \pgfmathsetmacro\checkdistancesqr{ ( ({\xlist}[\j]-(\x))^2 + ({\ylist}[\j]-(\y))^2 ) }
                \ifdim\checkdistancesqr pt<\diametersqr pt
                    \xdef\collision{1}
                    \breakforeach
                \fi
            }
            \ifnum\collision=0
                \xdef\xlist{\xlist,\x}
                \xdef\ylist{\ylist,\y}
                \draw (\x,\y) circle [radius=#3] node[anchor=center] {#5};
                \breakforeach
            \fi 
        }
    }
}
\begin{document}
\begin{figure}
\begin{tikzpicture}
\begin{scope}[xshift=0.2cm,yshift=0.2cm]
\fillrandomly{3.6}{3.8}{0.15}{12}{$-$}
\fillrandomly{3.6}{3.8}{0.15}{12}{$+$}
\end{scope}
        \draw (0,5) -- (0,1);
\draw (0,1) .. controls (0,0) and (0,0) .. (1,0);
\draw (1,0) -- (3,0);
\draw (3,0) .. controls (4,0) and (4,0) .. (4,1);
\draw (4,1) -- (4,5);
\draw[densely dashed] (0,5) .. controls (0,4.5) and (0,4.5) .. (0.5,4.5);
\draw[densely dashed] (0.5,4.5) -- (3.5,4.5);
\draw[densely dashed] (3.5,4.5) .. controls (4,4.5) and (4,4.5) .. (4,5);
\node[anchor=center] at (2,-0.5) {concentrated strong acid};

    \begin{scope}[xshift=5cm]
                \foreach \X in {1,...,3}
            {\draw (2+1.8*rand,2+1.9*rand) circle (0.15) node[anchor=center] {$+$};
            \draw (2+1.8*rand,2+1.9*rand) circle (0.15) node[anchor=center] {$-$};}
        \draw (0,5) -- (0,1);
\draw (0,1) .. controls (0,0) and (0,0) .. (1,0);
\draw (1,0) -- (3,0);
\draw (3,0) .. controls (4,0) and (4,0) .. (4,1);
\draw (4,1) -- (4,5);
\draw[densely dashed] (0,5) .. controls (0,4.5) and (0,4.5) .. (0.5,4.5);
\draw[densely dashed] (0.5,4.5) -- (3.5,4.5);
\draw[densely dashed] (3.5,4.5) .. controls (4,4.5) and (4,4.5) .. (4,5);
\node[anchor=center] at (2,-0.5) {dilute strong acid};
\end{scope}
    \begin{scope}[xshift=10cm]
\begin{scope}[xshift=0.2cm,yshift=0.2cm]
\fillrandomly{3.6}{3.8}{0.15}{8}{$-$}
\fillrandomly{3.6}{3.8}{0.15}{8}{$+$}
\end{scope}
\foreach \X in {1,...,8}
{
            \draw[fill=black!10]  (2+1.8*rand,2+1.9*rand) circle (0.15);
            }
        \draw (0,5) -- (0,1);
\draw (0,1) .. controls (0,0) and (0,0) .. (1,0);
\draw (1,0) -- (3,0);
\draw (3,0) .. controls (4,0) and (4,0) .. (4,1);
\draw (4,1) -- (4,5);
\draw[densely dashed] (0,5) .. controls (0,4.5) and (0,4.5) .. (0.5,4.5);
\draw[densely dashed] (0.5,4.5) -- (3.5,4.5);
\draw[densely dashed] (3.5,4.5) .. controls (4,4.5) and (4,4.5) .. (4,5);
\node[anchor=center] at (2,-0.5) {concentrated weak acid};
\end{scope}
        \begin{scope}[xshift=15cm]
                \foreach \X in {1,...,2}
            {\draw (2+1.8*rand,2+1.9*rand) circle (0.15) node[anchor=center] {$+$};
            \draw (2+1.8*rand,2+1.9*rand) circle (0.15) node[anchor=center] {$-$};}
            \draw[fill=black!10]  (2+1.8*rand,2+1.9*rand) circle (0.15);
        \draw (0,5) -- (0,1);
\draw (0,1) .. controls (0,0) and (0,0) .. (1,0);
\draw (1,0) -- (3,0);
\draw (3,0) .. controls (4,0) and (4,0) .. (4,1);
\draw (4,1) -- (4,5);
\draw[densely dashed] (0,5) .. controls (0,4.5) and (0,4.5) .. (0.5,4.5);
\draw[densely dashed] (0.5,4.5) -- (3.5,4.5);
\draw[densely dashed] (3.5,4.5) .. controls (4,4.5) and (4,4.5) .. (4,5);
\node[anchor=center] at (2,-0.5) {dilute weak acid};
\end{scope}
\draw[fill=black!10] (0,-1) circle (0.15) node[right=0.1cm] {Unionised};
\draw (0,-1.5) circle (0.15) node[anchor=center] {$+$} node[right=0.1cm] {Positive Ion};
\draw (0,-2) circle (0.15) node[anchor=center] {$-$} node[right=0.1cm] {Negative Ion}; 
\end{tikzpicture}
\vspace{-2cm}
\caption{Concentrated and dilute solutions of weak and strong acids}
\end{figure}
\end{document}

Which produces this image: enter image description here I am unsure how to stop overlapping between the three different types of circles especially in the first and third beaker counting from the left. XeLaTeX answer please

2
  • Lualatex ok?...
    – JPi
    Dec 16, 2018 at 12:23
  • Sorry I prefer XeLaTeX, forgot to mention
    – sab hoque
    Dec 16, 2018 at 12:23

1 Answer 1

6

It is clear why this happens: you draw two or more independent samples, so if you say e.g.

\fillrandomly{3.6}{3.8}{0.15}{12}{$-$} 
\fillrandomly{3.6}{3.8}{0.15}{12}{$+$} 

the + ions do not know about the - ones. But it is very simple to fix it. Just make the reset of the collision list not part of the \fillrandomly, but do it whenever you start a new group. That is, I redefined \fillrandomly such that it does not reset the collision list, and added a command \resetlists that issues the reset. I also defined an ion style that gets changed along the way such that one can add the filled ions.

\documentclass{article}
\usepackage{tikz}
\usepackage[margin=0.5in]{geometry}
\newcommand{\resetlists}{\xdef\xlist{4}\xdef\ylist{4}}
\newcommand{\fillrandomly}[5]{
    \pgfmathsetmacro\diametersqr{(#3*2)^2}
    \foreach \i in {1,...,#4}{
        \foreach \k in {1,...,20}{
            \pgfmathsetmacro\x{rnd*#1}
            \pgfmathsetmacro\y{rnd*#2}
            \xdef\collision{0}
            \foreach \element [count=\i] in \xlist{
                \pgfmathtruncatemacro\j{\i-1}
                \pgfmathsetmacro\checkdistancesqr{ ( ({\xlist}[\j]-(\x))^2 + ({\ylist}[\j]-(\y))^2 ) }
                \ifdim\checkdistancesqr pt<\diametersqr pt
                    \xdef\collision{1}
                    \breakforeach
                \fi
            }
            \ifnum\collision=0
                \xdef\xlist{\xlist,\x}
                \xdef\ylist{\ylist,\y}
                \draw[ion] (\x,\y) circle [radius=#3] node[anchor=center] {#5};
                \breakforeach
            \fi 
        }
    }
}
\begin{document}
\begin{figure}
\begin{tikzpicture}
\begin{scope}[xshift=0.2cm,yshift=0.2cm]
\resetlists
\tikzset{ion/.style={}}
\fillrandomly{3.6}{3.8}{0.15}{12}{$-$}
\fillrandomly{3.6}{3.8}{0.15}{12}{$+$}
\end{scope}
        \draw (0,5) -- (0,1);
\draw (0,1) .. controls (0,0) and (0,0) .. (1,0);
\draw (1,0) -- (3,0);
\draw (3,0) .. controls (4,0) and (4,0) .. (4,1);
\draw (4,1) -- (4,5);
\draw[densely dashed] (0,5) .. controls (0,4.5) and (0,4.5) .. (0.5,4.5);
\draw[densely dashed] (0.5,4.5) -- (3.5,4.5);
\draw[densely dashed] (3.5,4.5) .. controls (4,4.5) and (4,4.5) .. (4,5);
\node[anchor=center] at (2,-0.5) {concentrated strong acid};

% 2
\begin{scope}[xshift=5cm]
            \foreach \X in {1,...,3}
        {\draw (2+1.8*rand,2+1.9*rand) circle (0.15) node[anchor=center] {$+$};
        \draw (2+1.8*rand,2+1.9*rand) circle (0.15) node[anchor=center] {$-$};}
    \draw (0,5) -- (0,1);
\draw (0,1) .. controls (0,0) and (0,0) .. (1,0);
\draw (1,0) -- (3,0);
\draw (3,0) .. controls (4,0) and (4,0) .. (4,1);
\draw (4,1) -- (4,5);
\draw[densely dashed] (0,5) .. controls (0,4.5) and (0,4.5) .. (0.5,4.5);
\draw[densely dashed] (0.5,4.5) -- (3.5,4.5);
\draw[densely dashed] (3.5,4.5) .. controls (4,4.5) and (4,4.5) .. (4,5);
\node[anchor=center] at (2,-0.5) {dilute strong acid};
\end{scope}

% 3
\begin{scope}[xshift=10cm]
\begin{scope}[xshift=0.2cm,yshift=0.2cm]
\resetlists
\tikzset{ion/.style={}}
\fillrandomly{3.6}{3.8}{0.15}{8}{$-$}
\fillrandomly{3.6}{3.8}{0.15}{8}{$+$}
\tikzset{ion/.style={fill=black!10}}
\fillrandomly{3.6}{3.8}{0.15}{8}{}
\end{scope}
\draw (0,5) -- (0,1);
\draw (0,1) .. controls (0,0) and (0,0) .. (1,0);
\draw (1,0) -- (3,0);
\draw (3,0) .. controls (4,0) and (4,0) .. (4,1);
\draw (4,1) -- (4,5);
\draw[densely dashed] (0,5) .. controls (0,4.5) and (0,4.5) .. (0.5,4.5);
\draw[densely dashed] (0.5,4.5) -- (3.5,4.5);
\draw[densely dashed] (3.5,4.5) .. controls (4,4.5) and (4,4.5) .. (4,5);
\node[anchor=center] at (2,-0.5) {concentrated weak acid};
\end{scope}

%4
\begin{scope}[xshift=15cm]
\begin{scope}[xshift=0.2cm,yshift=0.2cm]
\resetlists
\tikzset{ion/.style={}}
\fillrandomly{3.6}{3.8}{0.15}{2}{$-$}
\fillrandomly{3.6}{3.8}{0.15}{2}{$+$}
\tikzset{ion/.style={fill=black!10}}
\fillrandomly{3.6}{3.8}{0.15}{1}{}
\end{scope}
\draw (0,5) -- (0,1);
\draw (0,1) .. controls (0,0) and (0,0) .. (1,0);
\draw (1,0) -- (3,0);
\draw (3,0) .. controls (4,0) and (4,0) .. (4,1);
\draw (4,1) -- (4,5);
\draw[densely dashed] (0,5) .. controls (0,4.5) and (0,4.5) .. (0.5,4.5);
\draw[densely dashed] (0.5,4.5) -- (3.5,4.5);
\draw[densely dashed] (3.5,4.5) .. controls (4,4.5) and (4,4.5) .. (4,5);
\node[anchor=center] at (2,-0.5) {dilute weak acid};
\end{scope}
\draw[fill=black!10] (0,-1) circle (0.15) node[right=0.1cm] {Unionised};
\draw (0,-1.5) circle (0.15) node[anchor=center] {$+$} node[right=0.1cm] {Positive Ion};
\draw (0,-2) circle (0.15) node[anchor=center] {$-$} node[right=0.1cm] {Negative Ion}; 
\end{tikzpicture}
\vspace{-2cm}
\caption{Concentrated and dilute solutions of weak and strong acids}
\end{figure}
\end{document}

enter image description here

2
  • I may have misunderstood something, but is the only thing that was changed was the addition of an ion style. I can't see where the cahnge was made to prevent the resetting of the list? I like to understand the code before I use it
    – sab hoque
    Dec 16, 2018 at 14:04
  • 2
    @sabhoque No, the original code has \xdef\xlist{4}\xdef\ylist{4} part of \fillrandomly. This resets the collision list, i.e. the list of previous positions of ions. Whenever a new ion is placed, \fillrandomly checks if the would-be ion overlaps with one of the previous ones. If not, the ion is drawn. All I did was not to reset the list automatically. So in the first example the + ions also know where the - ions were. I only reset the list when I switch to the next container. The ion style allows you to draw the shaded circles with \fillrandomly, too.
    – user121799
    Dec 16, 2018 at 14:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .