[Tex/LaTex] How to divide a colour wheel into n segments

colordiagramsdrawtikz-pgf

Sometimes when drawing a diagram, you want a certain number of similar objects of different colours, but the number might vary and you don't want to have to go through and manually define and assign all the colours individually, especially if you're iterating over a set of variables. Regardless of the quantity of objects, you want the transition of colours to appear smooth and evenly spaced, so that it flows and creates an illusion of natural progression.


This image is produced with a nice, simple \foreach loop. A template is shown below.
Each integer in the set is denoted \int and the colour at each iteration is \hue. The value of \int is applied to the name of each node, the corresponding x-coordinate, and the associated text (i.e., the label inside the circle): (\int) at (\int,0) {\int};.
fill=\hue!50
The two variables are declared together:
\foreach \int/\hue
And then defined together for each iteration:
{1/red,2/orange,3/yellow,4/green,5/cyan,6/blue,7/violet}
So 1 is associated with red, 2 with orange, and so on.
fill=\hue!20,color=\hue
It's probably not perfect because we're using the predefined colours, but you get the idea. Something similar (more complex, modulates saturation) can be seen here, but I was never quite able to understand it. I'd prefer to adjust hue only, not saturation. Saturation is already easily adjusted by appending a ! value to the colour, (e.g., \hue!20).


\documentclass[margin=10]{standalone}
\usepackage{tikz}

\begin{document}
    \begin{tikzpicture}
        \foreach \int/\hue in 
        {1/red,2/orange,3/yellow,4/green,5/cyan,6/blue,7/violet}
            \node[draw,circle,color=black,fill=\hue!50] 
            (\int) at (\int,0) {\int};
    \end{tikzpicture}
\end{document}

To help illustrate what I want to achieve, here are some reference diagrams from LightColourVision. Notice how the saturation is uniform, and the spectrum is evenly divided at every stage.

enter image description here
enter image description here


The idea is probably best summed up as such:

Automatic coloring may be useful in graphics or chart applications, where a potentially large and unspecified number of colors are needed,
and the user does not want or is not able to specify each individual
color.
xcolor manual

Here's my best attempt so far:

\documentclass[rgb,tikz,dvipsnames,margin=10]{standalone}
\begin{document}
\definecolorseries{wheel}{hsb}{step}{OrangeRed}[hsb]{.046,0,0}
\resetcolorseries{wheel}
\begin{tikzpicture}
    \foreach \int in {1,...,10}
        \node[draw,circle,minimum size=22,fill=wheel!!+!50] 
        (\int) at (\int,0) {\int};
\end{tikzpicture}
\end{document} 

enter image description here
It's just hacked together; I don't understand it well, and I'm not totally satisfied with it.

Best Answer

Note that with blue!50 you define a color that is 50% of blue. This is a very different approach to adjusting hue and saturation with a HSB color model, which I would suggest using here. With the xcolor package (or TikZ) you can define a color using the Hsb model that takes a number between 0 and 360 to define the hue (which you can easily divide through the number of steps that you want), and numbers between 0 and 1 for both saturation and brightness.

So, perhaps you can start with:

\documentclass[margin=10]{standalone}
\usepackage[rgb]{xcolor} 
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
    \foreach \hue in {0,...,6}
        \pgfmathparse{360/7*\hue}
        \definecolor{current}{Hsb}{\pgfmathresult,.5,1}
        \node[draw,circle,fill=current] (\hue) at (\hue,0) {\hue};
\end{tikzpicture}
\end{document}

enter image description here

Note that you probably need to separately load the xcolor package with rgb option to convert colours into the RGB model for output.


Approach for a wheel:

\documentclass[border=5pt]{standalone}
\usepackage[rgb]{xcolor} 
\usepackage{tikz}

\newcommand{\colorring}[4][1]{
    \def\segments{#2}
    \def\innerrad{#3}
    \def\outerrad{#4}
    \foreach \x in {1,...,\segments}
        \pgfmathparse{360/\segments*\x}
        \definecolor{current}{Hsb}{\pgfmathresult,#1,1}
        \fill[current,draw=white] (360/\segments*\x-360/\segments/2:\outerrad) 
            arc (360/\segments*\x-360/\segments/2:360/\segments*\x+360/\segments/2:\outerrad) 
            -- (360/\segments*\x+360/\segments/2:\innerrad) 
            arc (360/\segments*\x+360/\segments/2:360/\segments*\x-360/\segments/2:\innerrad) 
            -- cycle;
}

\begin{document}

\begin{tikzpicture}[scale=2, rotate=90]

\colorring{3}{0cm}{3mm}
\colorring[.9]{6}{3mm}{5mm}
\colorring[.8]{18}{5mm}{7mm}
\colorring[.7]{30}{7mm}{9mm}
\colorring[.6]{102}{9mm}{11mm}

\end{tikzpicture}

\end{document}

enter image description here