6

I would like to draw concentric circles like these:

enter image description here

by means of TikZ and \foreach command. The way I achieved it is very elementary (and burdensome):

   \documentclass[standalone]
   \usepackage{tikz}
   \begin{document}
   \begin{tikzpicture}[scale=0.2]
   \coordinate (O) at (0,0);
   \fill[red!70] (O) circle (20);
   \fill[white] (O) circle (19);
   \fill[yellow!70] (O) circle (18);
   \fill[white] (O) circle (17);
   \fill[red!70] (O) circle (16);
   \fill[white] (O) circle (15);
   \fill[yellow!70] (O) circle (14);
   \fill[white] (O) circle (13);
   \fill[red!70] (O) circle (12);
   \fill[white] (O) circle (11);
   \fill[yellow!70] (O) circle (10);
   \fill[white] (O) circle (9);
   \fill[red!70] (O) circle (8);
   \fill[white] (O) circle (7);
   \fill[yellow!70] (O) circle (6);
   \fill[white] (O) circle (5); 
   \fill[red!70] (O) circle (4);
   \fill[white] (O) circle (3);
   \fill[yellow!70] (O) circle (2);
   \fill[white] (O) circle (1);
   \end{tikzpicture}
   \end{document}

To no avail did I try applying \foreach, but this is definitely due to my lack of fluency with TikZ (I always ended up with one color, or at most two nested circle with different color). Could you be so kind and help me with these? A suggestion how to do this would be even better than the full answer.

7 Answers7

10

You mean something like this:

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[mystyle/.style={circle,draw,fill=none,minimum size=20, line width = 8pt}]
  \foreach \x in {1,3,5,7,9,11,13,15,17,19}
\node [mystyle,  minimum size = \x cm, color =red!70]  (2) at (0, 0) {};
  \foreach \x in {2,4,6,8,10,12,14,16,18, 20}
\node [mystyle,  minimum size = \x cm, color =yellow!50]  (2) at (0, 0) {};
\end{tikzpicture}
\end{document}  

which would give you:

enter image description here

I just made the yellow a bit lighter because, it was bleeding yellow too much :D

8

A slight generalization of Raaja's and TeXncian's answers in that I allow arbitrary color cycle lists, which is illustrated by an additional list of length 3.

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\begin{tikzpicture}
\def\lstColors{{"red!70","yellow!50"}}
\foreach \X [evaluate=\X as \Col using {\lstColors[int(mod(\X,2))]}] in {1,...,20}
{\draw[line width = 8pt,\Col] (0,0) circle (\X);}
\end{tikzpicture}
\begin{tikzpicture}
\def\lstColors{{"red!70","yellow!50","blue!70"}}
\foreach \X [evaluate=\X as \Col using {\lstColors[int(mod(\X,3))]}] in {1,...,20}
{\draw[line width = 8pt,\Col] (0,0) circle (\X);}
\end{tikzpicture}
\end{document}

enter image description here

  • 1
    Neat. I'd wondered how to do that... I'm certainly missing something basic, but for \X=1 (the innermost circle) shouldn't that be red? The fix is simple, just reverse the order of the colors in \lstColors, but just wondered... – sgmoye Jan 23 '19 at 15:10
  • @sgmoye Good catch. The index of the first element of the list is 0, and the one of the second is 1. That's where the flip comes from. (I'll keep it to make the screenshots here more diverse. ;-) –  Jan 23 '19 at 22:04
  • I saw that, and to counteract it I changed {\lstColors[int(mod(\X,2))]} to {\lstColors[int(mod(\X-1,2))]} in my copy -- that seemed to work for both 2 and 3 colors. Still, nice work! (Been a long day or I'd have posted earlier...) – sgmoye Jan 23 '19 at 22:58
7

A PSTricks solution.

\documentclass[pstricks]{standalone}
\psset{runit=4pt,unit=\psrunit}
\begin{document}
\pspicture[linewidth=.5](-11,-11)(11,11)
    \foreach \i in {1,2,...,10}{%
        \ifodd\i\def\c{yellow}\else\def\c{red}\fi
        \pscircle[linecolor=\c]{\i}}
\endpspicture
\end{document}

enter image description here

Note: There is an unnecessary white spot after converting to PNG.

Animated version

\documentclass[pstricks]{standalone}
\psset{runit=4pt,unit=\psrunit}
\begin{document}    
\foreach \j in {1,...,10}{%
\pspicture[linewidth=.5](-11,-11)(11,11)
    \foreach \i in {1,...,\j}{%
        \ifodd\i\def\c{yellow}\else\def\c{red}\fi
        \pscircle[linecolor=\c]{\i}}%
\endpspicture}
\end{document}

enter image description here

Display Name
  • 46,933
5

A SkiaSharp solution only for comparison purposes.

using SkiaSharp; // needs skiasharp nuget
using System.Diagnostics;


class ConcentricCircle
{
    static readonly SKPaint yellowStroke = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        Color = SKColors.Yellow,
        IsAntialias = true
    };


    static readonly SKPaint redStroke = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        Color = SKColors.Red,
        IsAntialias = true
    };

    static readonly float scale = SKDocument.DefaultRasterDpi / 2.54f; // dots per cm
    static readonly float width = 6 * scale; // 6 cm
    static readonly float height = 6 * scale; // 6 cm

    static float PtToCm(float pt) => pt / scale;



    public static void Generate(string filename)
    {
        yellowStroke.StrokeWidth = PtToCm(4); // 4pt
        redStroke.StrokeWidth = PtToCm(4); // 4pt

        using (var stream = new SKFileWStream($"{filename}.pdf"))
        using (var document = SKDocument.CreatePdf(stream))
        using (var canvas = document.BeginPage(width, height))
        {

            // translate first and then scale, don't reverse!
            canvas.Translate(width / 2, height / 2);
            canvas.Scale(scale);

            // draw a red circle
            for (int i = 0; i < 5; i++)
            {
                canvas.DrawCircle(0, 0, PtToCm(8) * (2 * i + 1), yellowStroke);
                canvas.DrawCircle(0, 0, PtToCm(8) * (2 * i + 2), redStroke);
            }

            document.EndPage();
        }
    }

    private static void Main()
    {
        string filename = nameof(ConcentricCircle);
        Generate(filename);

        // convert to PNG with ImageMagick
        using (Process p = new Process())
        {
            p.StartInfo.FileName = "magick";
            p.StartInfo.Arguments = $"convert -compose copy -bordercolor red -border 2x2 -density 200 -alpha remove {filename}.pdf {filename}.png";
            p.Start();
        }
    }
}

enter image description here

Display Name
  • 46,933
5

This is Raaja's solution but without the second loop (test if the count variable is odd) and with a simple draw instead of nodes (change line width to make it thicker).

concentric circles

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[mystyle/.style={circle,draw,fill=none,minimum size=20, line width = 8pt}]
  \foreach \x in {1,...,20}{
    \pgfmathparse{isodd(\x)}\ifnum\pgfmathresult=1\def\currcol{red!70}\else\def\currcol{yellow!50}\fi
    \draw[line width=8pt,\currcol] (0,0) circle (\x cm);}
\end{tikzpicture}
\end{document}  
TeXnician
  • 33,589
4

Just for fun. Another solution which draws a couple of red and yellow circles in each iteration:

\documentclass[tikz,border=3mm]{standalone}

\usetikzlibrary{positioning}

\begin{document}
\begin{tikzpicture}[
    mycircle/.style={circle, draw, fill=none, line width=8pt},
    twocircle/.style={
        mycircle,
        minimum size=#1cm,
        color=yellow!70,
        append after command={%
            \pgfextra
                \node[mycircle, minimum size=\the\numexpr#1-1\relax cm, color=red!70] at (\tikzlastnode.center) {};
            \endpgfextra}},
]

\foreach \i in {2,4,...,12}
    \node[twocircle=\i] {};
\end{tikzpicture}
\end{document}

enter image description here

Ignasi
  • 136,588
2

A slightly different approach to the solution proposed @TeXnician (suggested by this: What is wrong with the use of `isodd` of `xifthen`?):

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[mystyle/.style={circle,draw,fill=none,minimum size=20, line width = 8pt}]
    \foreach \x in {1,2,...,19}{
        \pgfmathsetmacro\mycolor{isodd \x?"red!70":"yellow!50"}%
        \node [mystyle,  minimum size = \x cm, \mycolor]  (2) at (0, 0) {};
    }%
\end{tikzpicture}
\end{document}  
sgmoye
  • 8,586
  • Why do you refer to the post about xifthen? Neither I do use it nor do you. And you do not even need the \numexpr because \x already is a number (the number you want to check). – TeXnician Jan 23 '19 at 14:05
  • @TeXnician Had you checked, you would have seen that xifthen is in the title of the question from which I used some code, and which is substituted automatically for the URL. \numexpr is superfluous. Will remove. – sgmoye Jan 23 '19 at 14:39