TikZ 填充分数图

TikZ 填充分数图

我试图给这个圆的三分之一涂上阴影。显然,这行不通。我做错了什么?

我尝试了以下代码,两次都没有收到错误消息,但都没有填写任何内容。两次都只是给出了这个圆圈。

还不到三分之一

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

答案1

考虑到预期的应用,以下内容可能是一个有用的起点...

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

在此处输入图片描述

对于更一般的形状,可以假设每个分区都是相同的形状(如果不是,那就很棘手了)。因此,所需的最小值是

  • 代码移动到“包含”形状(例如圆形)的位置
  • 代码移动到适当的位置第形状划分
  • 代码来确定如何第形状划分被绘制
  • 代码来绘制每个形状划分(例如圆形扇区)。

这是一个相当通用的解决方案,以三角形形式表示:

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

在此处输入图片描述

重复使用fraction上面定义的图片(下面未显示),然后可以更加奢侈一些:

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

在此处输入图片描述

答案2

实际上存在两个问题。第一个问题是,arc构造必须遵循坐标规范。你不能从任何地方开始绘制圆弧。

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

这个更好:

第一次尝试

TikZ 现在正在填充路径 - 尽管不是您想要的路径。基本上,它正在构建路径,即圆弧。

开放路径

此路径(以红色显示)是开放的 - 并未封闭。因此,从技术上讲,没有太多需要填充的内容。由于您已请求填充,因此 TikZ 在这种情况下所做的是以最便捷的方式关闭路径:

封闭路径

这就是 TikZ 填充的内容。因此,您需要明确告诉它如何关闭路径:

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

正确关闭路径

这样要好得多,但填充将覆盖之前绘制的路径。最好在绘制其他路径之前填充该区域:

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

首先填充正确封闭的路径

答案3

由于该问题已在其他答案中得到解决,并在 cfr 中进行了详细解释回答,绘图的优化仍然存在。整个图像可以在一个\path命令中填充和绘制。技巧是基于使用非零填充规则。

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

答案4

您需要一条包围要填充区域的路径,而不仅仅是圆弧(先填充,后绘制);例如:

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

在此处输入图片描述

相关内容