11

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}
18

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

  • 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 5 '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 6 '15 at 7:27
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

  • 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 5 '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 5 '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}   
  • 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 5 '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 5 '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 7 '15 at 1: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 7 '15 at 5:02
  • How big of a difference would this optimization make for PDF file size? – WeCanLearnAnything Aug 8 '15 at 0:40
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

  • 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 4 '15 at 23:56
  • @cfr Well, thst's kind of obvious. I addressed the filling problem. – Gonzalo Medina Aug 4 '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 5 '15 at 0: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 5 '15 at 0: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 5 '15 at 0:10

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.