15

I'm trying to shade in one third of this circle. Obviously, it's not working. What did I do wrong?

I got no error messages for either of my attempts in the code below, but neither filled anything in. Both just gave this circle.

not yet one third

\documentclass[12pt,letterpaper]{article}

\usepackage{tikz}
\usepackage{xcolor}

\begin{document}

How to shade in $\frac{1}{3}$ of this?

\begin{tikzpicture}
\draw (0,0) circle (3cm);
\draw (90:3)--(0,0);
\draw (210:3)--(0,0);
\draw (330:3)--(0,0);
\fill[gray] arc[start angle=-30, end angle =90, radius=3cm];
\end{tikzpicture}

% In this attempt, I put the color=gray part in the same square brackets as all the other stuff.
\begin{tikzpicture}
\draw (0,0) circle (3cm);
\draw (90:3)--(0,0);
\draw (210:3)--(0,0);
\draw (330:3)--(0,0);
\fill arc[color=gray, start angle=-30, end angle =90, radius=3cm];
\end{tikzpicture}

\end{document}

4 Answers4

27

Considering the intended application, the following may be a useful starting point...

\documentclass[tikz, border=5]{standalone}
\newcount\segmentsleft
\tikzset{pics/.cd,
  circle fraction/.style args={#1/#2}{code={%
\segmentsleft=#1\relax
\pgfmathloop
\ifnum\segmentsleft<1\else
\ifnum\segmentsleft<#2 \edef\n{\the\segmentsleft}\else\def\n{#2}\fi
\begin{scope}[shift={(\pgfmathcounter,0)}]
\foreach \i [evaluate={\a=360/#2*(\i-1)+90;}] in {1,...,\n}
  \fill[fill=gray] (0,0) -- (\a:3/8) arc (\a:\a+360/#2:3/8) -- cycle;
\draw circle [radius=3/8];
\ifnum#2>1
  \foreach \i [evaluate={\a=360/#2*(\i-1);}] in {1,...,#2}
    \draw (0,0) -- (90+\a:3/8);
\fi
\end{scope}
\advance\segmentsleft by-#2
\repeatpgfmathloop
  }}
}

\begin{document}
\begin{tikzpicture}
\foreach \numerator/\denominator [count=\y] 
  in {1/1, 1/3, 2/4, 3/5, 8/8, 4/1, 10/3, 20/6, 30/7, 40/15}{
  \node at (-1/2,-\y) {$\frac{\numerator}{\denominator}$};
  \pic  at (0, -\y) {circle fraction={\numerator/\denominator}};
}
\end{tikzpicture}

enter image description here

For more general shapes, one can assume that each division is the same shape (if it isn't it's going to get tricky). So, the minimum that is required is

  • code to shift to the position for the "containing" shape (e.g., circle)
  • code to shift to the appropriate position for the ith shape-division
  • code to determine how the ith shape-division is drawn
  • code to draw each shape-division (e.g., circular sector).

Here is a reasonably general solution illustrated with a triangle style:

\documentclass[tikz, border=5]{standalone}
\newcount\tikzfractiondenominator
\newcount\tikzfractionnumerator
\def\tikzfractionempty{}
\let\tikzfractionstyle=\tikzfractionempty
\newif\iftikzfractionfill
\tikzset{pics/.cd,
  fraction/.style={%
    code={%
      \tikzset{pics/fraction/.cd, #1}%
      \pgfmathparse{int(ceil(\tikzfractionnumerator/\tikzfractiondenominator))}%
      \let\tikzfractionshapetotal=\pgfmathresult
      \ifx\tikzfractionstyle\tikzfractionempty
      \else%
        \pgfmathloop
          \ifnum\tikzfractionnumerator<1
        \else
          \pgfmathsetmacro\tikzfractionproper{int(\tikzfractionnumerator?\tikzfractionnumerator:\tikzfractiondenominator)}%
          \foreach \tikzfractionsegmentnumber in {1,...,\tikzfractiondenominator}{%
            \ifnum\tikzfractionsegmentnumber>\tikzfractionproper\relax%
              \tikzfractionfillfalse%
            \else%
              \tikzfractionfilltrue%
            \fi%
            \let\tikzfractionshapenumber=\pgfmathcounter%
            \begin{scope}
              \tikzset{pics/fraction/\tikzfractionstyle/shape position/.try}%
              \tikzset{pics/fraction/\tikzfractionstyle/segment position/.try}%
              \tikzset{pics/fraction/\tikzfractionstyle/segment draw/.try}%
            \end{scope}
          }% 
          \advance\tikzfractionnumerator by-\tikzfractiondenominator%
        \repeatpgfmathloop%
      \fi%
    }
  },
  fraction/.cd,
    style/.store in=\tikzfractionstyle,
    numerator/.code=\pgfmathsetcount\tikzfractionnumerator{#1},
    denominator/.code=\pgfmathsetcount\tikzfractiondenominator{#1},
    fraction/.style args={#1/#2}{%
      /tikz/pics/fraction/.cd,
        numerator={#1}, denominator={#2}
    }
}
\tikzset{%
  /tikz/pics/fraction/triangles/.cd,
    shape position/.code={
      \pgfmathsetmacro\y{sqrt(\tikzfractiondenominator)}
      \tikzset{
        shift=(0:{(\tikzfractionshapenumber-1)*\y}),
        shift={(0,\y/4)},
      }
    },
    segment position/.code={
      \let\i=\tikzfractionsegmentnumber
      \pgfmathsetmacro\z{int(sqrt(\i-1))}
      \pgfmathsetmacro\q{\i-(\z)^2}
      \tikzset{
        shift={({sin(60) * (\q-\z) / 2}, {-\z*0.75 -mod(\q,2)*cos(60)/2})},
        rotate={mod(\q-1,2)*180}
      }
    },
    segment draw/.code={
      \iftikzfractionfill
        \tikzset{triangle fill/.style={blue!50!cyan!50}}
      \else
        \tikzset{triangle fill/.style={gray!20}}
      \fi
      \fill [triangle fill] (90:0.45) -- (210:0.45) -- (330:0.45) -- cycle;
    }
}
\begin{document}
\begin{tikzpicture}
\foreach \numerator/\denominator [count=\y]  in {1/1, 2/4, 13/9}{
\tikzset{shift=(270:\y*2)}
\pic {fraction={style=triangles, fraction={\numerator/\denominator}}};
\node at (-1,0)  {$\frac{\numerator}{\denominator}$};
}
\end{tikzpicture}
\end{document}

enter image description here

Reusing the fraction pic defined above (not shown below), it is then possible to be a bit more extravagant:

\tikzset{%
  /tikz/pics/fraction/petals/.cd,
    shape position/.code={
      \tikzset{
        shift=(360/\tikzfractionshapetotal*\tikzfractionshapenumber:2)
      }
    },
    segment position/.code={
      \tikzset{
        rotate=(360/\the\tikzfractiondenominator*\tikzfractionsegmentnumber)
      }
    },
    segment draw/.code={
      \iftikzfractionfill
        \tikzset{petal/.style={bottom color=purple, top color=pink}}
      \else
        \tikzset{petal/.style={bottom color=yellow!50, top color=orange!50}}
      \fi
      \pgfmathparse{180/\tikzfractiondenominator}%
      \let\r=\pgfmathresult
      \path [petal] (0:0) [rounded corners=1ex] -- 
        (-\r:0.5) -- (0:.75) -- (\r:0.5) -- cycle;
    }
}
\begin{tikzpicture}
\pic {fraction={style=petals, fraction={53/8}}};
\node {$\frac{53}{8}$};
\end{tikzpicture}

enter image description here

Mark Wibrow
  • 70,437
  • This looks incredible! Thanks! I'm a newb so it may take me, oh, 2 weeks or so to make sense of the code, lol, but I'll do it for sure. Can I ask where you found this code and packages and whether there is something similar for other shapes (non-circles)? – WeCanLearnAnything Aug 05 '15 at 18:59
  • @WeCanLearnAnything this code came from my head ;) other shapes are possible, it depends on the shape is divided up. – Mark Wibrow Aug 06 '15 at 07:27
  • I'd like to modify your first code for a little more flexible - eg. varying the circle's radius. Changed the line circle fraction/.style args={#1/#2}{code={% to circle fraction/.style args={#1/#2,#3}{code={% and changed the hardcoded 3/8 radius to #3. When compiling, the macro fails with "Runaway argument". – Thomas Benko Sep 12 '19 at 19:21
  • Hi Mark, could you add square grids (helpful for visualizing tenths, hundredths & percents) to your example? These are nice for representing tenths (using a 10x1 grid) or percents (using a 10x10 square grid). Similar to this: https://tex.stackexchange.com/questions/274219/drawing-a-multicolored-grid-using-tikz – EthanAlvaree Dec 11 '19 at 06:08
  • Or another nice way to represent percents, with 100 tiny small circles in a 10x10 grid, with the desired number of circles shaded? Thanks in advance @MarkWibrow for the great code!! – EthanAlvaree Dec 11 '19 at 06:08
  • Part 3: How can I modify the triangles example to draw black lines rather than leave white gaps/spaces between the triangles? – EthanAlvaree Jan 16 '20 at 19:56
  • @MarkWibrow Hi, your answer is excellent. I'm trying to make the circles bigger and managed to make the radius and fill to 1cm but I"m trying to separate the circles. Can you give me a hint on how to proceed? – E.Yu Apr 17 '20 at 03:44
11

There are really two problems. The first is that the arc construction must follow a coordinate specification. You cannot start an arc from nowhere.

\documentclass[tikz,border=10pt,multi,12pt]{standalone}
\begin{document}
\begin{tikzpicture}
  \draw (0,0) circle (3cm)
   (90:3)--(0,0)
   (210:3)--(0,0)
   (330:3)--(0,0);
  \fill [gray] (330:3) arc[start angle=-30, end angle =90, radius=3cm];
\end{tikzpicture}
\end{document}

This is better:

first attempt

TikZ is now filling a path - albeit not the path you'd like. Basically what is happening is that it is constructing the path which is the arc.

open path

This path (shown in red) is open - it is not closed. So there is, technically, not much to fill. What TikZ does in this case, since you've requested it be filled is to close the path in the most expedient way:

closed path

And this is what TikZ fills. So you need to tell it explicitly how to close the path:

\documentclass[tikz,border=10pt,multi,12pt]{standalone}
\begin{document}
\begin{tikzpicture}
  \draw (0,0) circle (3cm)
   (90:3)--(0,0)
   (210:3)--(0,0)
   (330:3)--(0,0);
  \fill [gray] (330:3) arc[start angle=-30, end angle =90, radius=3cm] -- (0,0) -- cycle;
\end{tikzpicture}
\end{document}

properly closing the path

This is much better but the fill will be filled over the paths drawn earlier. Best is to fill the area before drawing the other paths:

\documentclass[tikz,border=10pt,multi,12pt]{standalone}
\begin{document}
\begin{tikzpicture}
  \fill [gray] (330:3) arc[start angle=-30, end angle =90, radius=3cm] -- (0,0) -- cycle;
  \draw (0,0) circle (3cm)
   (90:3)--(0,0)
   (210:3)--(0,0)
   (330:3)--(0,0);
\end{tikzpicture}
\end{document}

properly closed path filled first

cfr
  • 198,882
  • Ok, got it. Thanks! This makes a lot more sense now. For some reason, I just assumed that the arc would know to use (0,0) as its reference point, but now I know it has to be written in explicitly. – WeCanLearnAnything Aug 05 '15 at 19:02
  • @WeCanLearnAnything Glad it helped. It is confusing because if you say \coordinate (a); or \node {A};, TikZ will assume a default position - you'll get your coordinate or your node, typically at (0,0). But it doesn't always work that way for other things, including arcs :(. – cfr Aug 05 '15 at 20:38
6

Since the problem is solved in the other answers with an detailed explanation in cfr's answer, the optimization of the drawing remains. The whole image can be filled and drawn in one \path command. The trick is based on using the nonzero filling rule.

\documentclass[12pt,letterpaper]{article}

\usepackage{tikz}
\usepackage{xcolor}

\begin{document}
\begin{tikzpicture}
  \draw[fill=gray, radius=3cm]
    (210:3cm) -- (0, 0) circle[]
    -- (-30:3cm) arc[start angle=-30, end angle=90] -- cycle
  ;
\end{tikzpicture}
\end{document}   
Heiko Oberdiek
  • 271,626
  • 1
    +1 Perfect for code golfing \tikz\draw[fill=gray](210:3)--(0,0)circle(3)--(330:3)arc(330:90:3)--cycle; ;) – Kpym Aug 05 '15 at 10:37
  • @ Heiko Oberdiek, Awesome! I'm going to try to make sense of that code today and get back to you. :) – WeCanLearnAnything Aug 05 '15 at 19:03
  • @ Heiko Oberdiek I just read about the two fill rules and I think I understand it all. What I don't quite understand is how and why your code is considered optimized compared to mine. I'm a newb and you're obviously not, so I'm sure your code is better, but I don't know why. What am I missing there? – WeCanLearnAnything Aug 07 '15 at 01:59
  • @WeCanLearnAnything Main optimization goal was the number of PDF page operations. The drawing uses 17. In comparison, the code at the end of cfr's answer uses 27, but is easier to read. Thus, the optimization decreases the PDF operations, the PDF file size, and source code size. The latter is taken to its extreme by the code golf version of Kpym's comment. – Heiko Oberdiek Aug 07 '15 at 05:02
  • How big of a difference would this optimization make for PDF file size? – WeCanLearnAnything Aug 08 '15 at 00:40
  • @WeCanLearnAnything Few bytes. – Heiko Oberdiek Aug 08 '15 at 03:42
3

You need a path enclosing an area to fill, not just the arc (fill first, draw later); for example:

\documentclass[12pt,letterpaper]{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\fill[gray]
  (0,0) --
  (-30:3) 
  arc[start angle=-30, end angle =90, radius=3cm] -- 
  cycle;

\draw 
  (0,0) circle (3cm)
  (90:3)--(0,0)
  (210:3)--(0,0)
  (330:3)--(0,0);
\end{tikzpicture}

\end{document}

enter image description here

Gonzalo Medina
  • 505,128
  • That's a problem, I agree. But it does not explain why nothing is filled. (If it is \draw rather than \fill, there's no question of needing to close the path but TikZ still draws nothing.) Isn't the main problem that you cannot start an arc from nowhere? – cfr Aug 04 '15 at 23:56
  • @cfr Well, thst's kind of obvious. I addressed the filling problem. – Gonzalo Medina Aug 04 '15 at 23:58
  • 'Obvious' is relative. It... er... obviously isn't obvious to the OP else, presumably, the arc in the MWE would have started somewhere ;). But, also, I'm not sure it is obvious in general. After all, I can say \node (a) {A}; and TikZ will not simply fail to create the node. Or I can say \coordinate (a); and get a coordinate. Why shouldn't paths assume a default starting point in the same way? [I know they don't but to claim this is 'obvious' strikes me as an insider's perspective ;). It is 'obvious' in the same way that the l3 syntax is 'obvious'. That is, not at all.] – cfr Aug 05 '15 at 00:01
  • @cfr It's obvious in the sense that Section 2.10 of the manual mentions this explicitly: "When one uses the arc path construction operation, the specified arc will be added with its starting point at the current position. So, we first have to “get there.”" (the boldface is mine). – Gonzalo Medina Aug 05 '15 at 00:07
  • @cfr But, yes, I see your point. In fact, I usually refrain myself from using "obvious" and such expressions. Perhaps it's a result of too much time of use of the basic TikZ's constructs. – Gonzalo Medina Aug 05 '15 at 00:10
  • By that criterion the closure point is equally obvious. From section 15.5: 'All unclosed parts of the path are first closed, if necessary. Then, the area enclosed by the path is filled with the current filling color...'. Moreover, 99% of TikZ questions and 90%+ of questions generally could be answered in 4 words with 'It's obvious, innit?' – cfr Aug 05 '15 at 00:22
  • @cfr I already mentioned that I tend not to use the word, so I see no point in keeping this discussion. – Gonzalo Medina Aug 05 '15 at 00:30
  • Sorry. I probably overreacted to the previous comment about it being obvious from the manual. – cfr Aug 05 '15 at 00:35