
Рассмотрим следующий пример.
\documentclass{beamer}
\usepackage[locale = DE]{siunitx}
\usepackage{xfp}
\usepackage{etoolbox}
\usepackage{pstricks-add}
\usepackage{tikz}
\psset{dimen = m}
% data
\def\bredde{4.5}
\def\start{0}
\def\eleverNul{4}
\def\eleverEn{2}
\def\eleverTo{5}
\def\eleverTre{7}
\def\eleverFire{5}
\def\eleverFem{3}
% beregninger
\newcommand*\eleverSumNul{\eleverNul}
\newcommand*\eleverSumEn{\fpeval{\eleverSumNul+\eleverEn}}
\newcommand*\eleverSumTo{\fpeval{\eleverSumEn+\eleverTo}}
\newcommand*\eleverSumTre{\fpeval{\eleverSumTo+\eleverTre}}
\newcommand*\eleverSumFire{\fpeval{\eleverSumTre+\eleverFire}}
\newcommand*\eleverSumFem{\fpeval{\eleverSumFire+\eleverFem}}
\newcommand*\eleverTotal{\fpeval{\eleverSumFem}}
\def\andelB[#1]#2#3#4{%
\pswedge[fillstyle = solid, fillcolor = #1]%
{\radius}{\fpeval{round(#2/\eleverTotal*360,9)}}{\fpeval{round(#3/\eleverTotal*360,9)}}
\ifstrequal{#1}{black}%
{\psarc[linecolor = white]%
(0,0){0.5}{\fpeval{round(#2/\eleverTotal*360,9)}}{\fpeval{round(#3/\eleverTotal*360,9)}}
\uput{8pt}[\fpeval{round((#2+#3)/\eleverTotal*180,9)}]%
(0,0){\textcolor{white}{\footnotesize\SI{\fpeval{round((#3-#2)/\eleverTotal*360)}}{\degree}}}}
{\psarc%
(0,0){0.5}{\fpeval{round(#2/\eleverTotal*360,9)}}{\fpeval{round(#3/\eleverTotal*360,9)}}
\uput{8pt}[\fpeval{round((#2+#3)/\eleverTotal*180,9)}]%
(0,0){\footnotesize\SI{\fpeval{round((#3-#2)/\eleverTotal*360)}}{\degree}}}%
}
\begin{document}
\begin{frame}{Opgave~$7$}
\begin{center}
\psset{
unit = 0.4,
linejoin = 1
}
\def\radius{5}
\begin{pspicture}(\fpeval{-(\radius+0.1)},\fpeval{-(\radius+0.1)})%
(\fpeval{+(\radius+0.1)},\fpeval{+(\radius+0.1)})
\visible<4->{%
\pscircle(0,0){\radius}
\multido{\r = 0+\fpeval{round(360/\eleverTotal,9)}}{\eleverTotal}{%
\psRelLine[angle = \r](0,0)(\fpeval{\radius+0.1},0){1}{EndNode}
\psRelLine[angle = \r, linecolor = white, linewidth = 2\pslinewidth]%
(0,0)(\fpeval{\radius-0.1},0){1}{EndNode}}}
\visible<5->{\andelB[yellow!70]{\start}{\eleverSumNul}}
\visible<6->{\andelB[red!70]{\eleverSumNul}{\eleverSumEn}}
\visible<7->{\andelB[green!80]{\eleverSumEn}{\eleverSumTo}}
\visible<8->{\andelB[orange!80]{\eleverSumTo}{\eleverSumTre}}
\visible<9->{\andelB[blue!70!white]{\eleverSumTre}{\eleverSumFire}}
\visible<10->{\andelB[black]{\eleverSumFire}{\eleverSumFem}}
\end{pspicture}
\end{center}
\end{frame}
\end{document}
Вопрос
Как можно заметить, 28°
этикетка не напечатана «поверх» зеленого клина. (Разумеется, то же самое касается и других этикеток.)
Как сделать так, чтобы этикетки всегда печатались «сверху»?
решение1
С небольшим изменением некоторых параметров:
\documentclass{beamer}
\usepackage[locale = DE]{siunitx}
\usepackage{xfp}
\usepackage{etoolbox}
\usepackage{pstricks-add}
\usepackage{tikz}
\psset{dimen = m}
% data
\def\bredde{4.5}
\def\start{0}
\def\eleverNul{4}
\def\eleverEn{2}
\def\eleverTo{5}
\def\eleverTre{7}
\def\eleverFire{5}
\def\eleverFem{3}
% beregninger
\newcommand*\eleverSumNul{\eleverNul}
\newcommand*\eleverSumEn{\fpeval{\eleverSumNul+\eleverEn}}
\newcommand*\eleverSumTo{\fpeval{\eleverSumEn+\eleverTo}}
\newcommand*\eleverSumTre{\fpeval{\eleverSumTo+\eleverTre}}
\newcommand*\eleverSumFire{\fpeval{\eleverSumTre+\eleverFire}}
\newcommand*\eleverSumFem{\fpeval{\eleverSumFire+\eleverFem}}
\newcommand*\eleverTotal{\fpeval{\eleverSumFem}}
\def\andelB[#1]#2#3#4{%
\pswedge[fillstyle = solid, fillcolor = #1]%
{\radius}{\fpeval{round(#2/\eleverTotal*360,9)}}{\fpeval{round(#3/\eleverTotal*360,9)}}
\ifstrequal{#1}{black}%
{\psarc[linecolor = white]%
(0,0){1.5}{\fpeval{round(#2/\eleverTotal*360,9)}}{\fpeval{round(#3/\eleverTotal*360,9)}}%
\uput{2}[\fpeval{round((#2+#3)/\eleverTotal*180,9)}]%8pt
(0,0){\textcolor{white}{\footnotesize\SI{\fpeval{round((#3-#2)/\eleverTotal*360)}}{\degree}}}}
{\psarc%
(0,0){1.5}{\fpeval{round(#2/\eleverTotal*360,9)}}{\fpeval{round(#3/\eleverTotal*360,9)}}%
%\def\r{}
\uput{2}[\fpeval{round((#2+#3)/\eleverTotal*180,9)}]%
(0,0){\footnotesize\SI{\fpeval{round((#3-#2)/\eleverTotal*360)}}{\degree}}}%
}
\begin{document}
\begin{frame}{Opgave~$7$}
\begin{center}
\psset{
unit = 0.4,
linejoin = 1
}
\def\radius{5}
\begin{pspicture}(\fpeval{-(\radius+0.1)},\fpeval{-(\radius+0.1)})%
(\fpeval{+(\radius+0.1)},\fpeval{+(\radius+0.1)})
\visible<4->{%
\pscircle(0,0){\radius}
\multido{\r = 0+\fpeval{round(360/\eleverTotal,9)}}{\eleverTotal}{%
\psRelLine[angle = \r](0,0)(\fpeval{\radius+0.1},0){1}{EndNode}
\psRelLine[angle = \r, linecolor = white, linewidth = 2\pslinewidth]%
(0,0)(\fpeval{\radius-0.1},0){1}{EndNode}}}
\visible<5->{\andelB[yellow!70]{\start}{\eleverSumNul}}
\visible<6->{\andelB[red!70]{\eleverSumNul}{\eleverSumEn}}
\visible<7->{\andelB[green!80]{\eleverSumEn}{\eleverSumTo}}
\visible<8->{\andelB[orange!80]{\eleverSumTo}{\eleverSumTre}}
\visible<9->{\andelB[blue!70!white]{\eleverSumTre}{\eleverSumFire}}
\visible<10->{\andelB[black]{\eleverSumFire}{\eleverSumFem}}
\end{pspicture}
\end{center}
\end{frame}
\end{document}
Добавлен: Используя значение 5.3 в качестве первого аргумента \uput
(вместо 2) в определении \andelB
, вы получите метку за пределами большого круга. (В этом случае не забудьте удалить \textcolor{white}
для черного сектора):
решение2
Обязательный аргумент для \uput{<distance>}
определяет расстояние от точки, на которую вы поместите содержимое, которое нужно поместить. Вы используете 8pt
в своем \andelB
макросе... увеличьте это до большего значения, например 25pt
:
\def\andelB[#1]#2#3#4{%
\pswedge[fillstyle = solid, fillcolor = #1]%
{\radius}{\fpeval{round(#2/\eleverTotal*360,9)}}{\fpeval{round(#3/\eleverTotal*360,9)}}
\ifstrequal{#1}{black}%
{\psarc[linecolor = white]%
(0,0){0.5}{\fpeval{round(#2/\eleverTotal*360,9)}}{\fpeval{round(#3/\eleverTotal*360,9)}}
\uput{25pt}[\fpeval{round((#2+#3)/\eleverTotal*180,9)}]%
(0,0){\textcolor{white}{\footnotesize\SI{\fpeval{round((#3-#2)/\eleverTotal*360)}}{\degree}}}}
{\psarc%
(0,0){0.5}{\fpeval{round(#2/\eleverTotal*360,9)}}{\fpeval{round(#3/\eleverTotal*360,9)}}
\uput{25pt}[\fpeval{round((#2+#3)/\eleverTotal*180,9)}]%
(0,0){\footnotesize\SI{\fpeval{round((#3-#2)/\eleverTotal*360)}}{\degree}}}%
}
решение3
\psset{
unit = 0.4,opacity=0.5,
linejoin = 1
}
Однако можно позволить \psChart
макросу выполнить все вычисления:
\documentclass{beamer}
\usepackage{pstricks-add}
\newcounter{temp}
\def\Chart{\psChart{55,28,69,97,69,42}{}{4}}
\begin{document}
\begin{frame}{Opgave~$7$}
\begin{center}
\begin{pspicture}(-3,-3)(3,3)
\visible<1->{%
\psset{userColor={yellow!70,white,white,white,white,white}}\Chart
\rput(psChartI1){55}}
\visible<2->{%
\psset{userColor={yellow!70,red!70,white,white,white,white}}\Chart
\rput(psChartI1){55}\rput(psChartI2){28}}
\visible<3->{%
\psset{userColor={yellow!70,red!70,green!80,white,white,white}}\Chart
\rput(psChartI1){55}\rput(psChartI2){28}\rput(psChartI3){69}}
\visible<4->{%
\setcounter{temp}{0}%
\psset{userColor={yellow!70,red!70,green!80,orange!80,white,white}}\Chart
\psforeach{\iA}{55,28,69,97}{\stepcounter{temp}\rput(psChartI\thetemp){\iA}}}
\visible<5->{%
\setcounter{temp}{0}%
\psset{userColor={yellow!70,red!70,green!80,orange!80,blue!70!white,white}}\Chart
\psforeach{\iA}{55,28,69,97,69}{\stepcounter{temp}\rput(psChartI\thetemp){\iA}}}
\visible<6>{%
\setcounter{temp}{0}%
\psset{userColor={yellow!70,red!70,green!80,orange!80,blue!70!white,black}}\Chart
\psforeach{\iA}{55,28,69,97,69}{\stepcounter{temp}\rput(psChartI\thetemp){\iA}}
\rput(psChartI6){\color{white}42}}
\pscircle{4}
\degrees[26]\multido{\iA=0+1}{26}{\psline(4;\iA)(4.1;\iA)}
\end{pspicture}
\end{center}
\end{frame}
\end{document}
решение4
Просто для развлечения: TiкАльтернатива Z. Вам нужно только указать списки чисел и цветов,
\def\LstNums{4,2,5,7,5,3}
\def\LstColors{"yellow!70","red!70","green!80","orange!80","blue!70!white","black"}
и код сделает все остальное. Цвета метки выбираются в дополнение к цвету заливки на основе цветовой модели RGB. (Вполне возможно, что другие цветовые модели выглядят лучше/иначе.) Таким образом, метки и внутренние дуги видны. Анимация начинается со слайда 4 ( \def\istart{4}
), как в вашем коде.
\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{overlay-beamer-styles,backgrounds}
% from https://tex.stackexchange.com/a/283618
\newcommand{\convertdirectly}[3][hsb]{\begingroup%
\extractcolorspecs{#2}{\modelcmd}{\colorcmd}%
\convertcolorspec{\modelcmd}{\colorcmd}{#1}{\tmp}%
\aftergroupdef#3\tmp}
\begin{document}
\begin{frame}[t]
\frametitle{Opgave~$7$}
\begin{center}
\begin{tikzpicture}[declare function={R=3;}]
\def\istart{4}
\def\LstNums{4,2,5,7,5,3}
\def\LstColors{"yellow!70","red!70","green!80","orange!80","blue!70!white","black"}
\def\mysum{0}
\foreach \X [remember=\mysum as \mysum]in \LstNums
{\pgfmathsetmacro{\mysum}{\mysum+\X}
\xdef\pgfmathresult{\mysum}}
\edef\mytotal{\pgfmathresult}
\pgfmathtruncatemacro{\mydim}{dim(\LstNums)-1}
\draw[thick,visible on=<\istart->] circle[radius=R*1cm]
foreach \X in {0,10,...,350} {(\X:R) -- (\X:R+0.05)};
\def\mysum{0}
\foreach \X [remember=\mysum as \mysum] in {0,...,\mydim}
{\pgfmathsetmacro{\mypercentage}{{\LstNums}[\X]/\mytotal}
\pgfmathsetmacro{\mycolor}{{\LstColors}[\X]}
\begin{scope}[on background layer]
\draw[visible on=<\the\numexpr\istart+1+\X\relax->,fill=\mycolor]
(0,0) -- (\mysum:R) arc(\mysum:\mysum+\mypercentage*360:R) --cycle;
\end{scope}
\convertdirectly[RGB]{\mycolor}{\currRGB}
\pgfmathtruncatemacro{\currR}{255-{\currRGB}[0]}
\pgfmathtruncatemacro{\currG}{255-{\currRGB}[1]}
\pgfmathtruncatemacro{\currB}{255-{\currRGB}[2]}
\definecolor{tmp}{RGB}{\currR,\currG,\currB}
\draw[visible on=<\the\numexpr\istart+1+\X\relax->,color=tmp,thick]
(\mysum:0.2*R) arc(\mysum:\mysum+\mypercentage*360:0.2*R)
(\mysum+\mypercentage*180:0.6*R) node
{$\pgfmathparse{int(360*\mypercentage+0.5)}\pgfmathresult^\circ$};
\pgfmathsetmacro{\mysum}{\mysum+{\LstNums}[\X]*360/\mytotal}
}
\end{tikzpicture}
\end{center}
\end{frame}
\end{document}
Если переместить метки ближе к центру, они не будут перекрашены клиньями, поскольку клинья нарисованы на background
слое.
\PassOptionsToPackage{cmyk}{xcolor}
\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{overlay-beamer-styles,backgrounds}
% from https://tex.stackexchange.com/a/283618
\newcommand{\convertdirectly}[3][hsb]{\begingroup%
\extractcolorspecs{#2}{\modelcmd}{\colorcmd}%
\convertcolorspec{\modelcmd}{\colorcmd}{#1}{\tmp}%
\aftergroupdef#3\tmp}
\begin{document}
\begin{frame}[t]
\frametitle{Opgave~$7$}
\begin{center}
\begin{tikzpicture}[declare function={R=3;}]
\def\istart{4}
\def\LstNums{4,2,5,7,5,3}
\def\LstColors{"yellow!70","red!70","green!80","orange!80","blue!70!white","black"}
\def\mysum{0}
\foreach \X [remember=\mysum as \mysum]in \LstNums
{\pgfmathsetmacro{\mysum}{\mysum+\X}
\xdef\pgfmathresult{\mysum}}
\edef\mytotal{\pgfmathresult}
\pgfmathtruncatemacro{\mydim}{dim(\LstNums)-1}
\draw[thick,visible on=<\istart->] circle[radius=R*1cm]
foreach \X in {0,10,...,350} {(\X:R) -- (\X:R+0.05)};
\def\mysum{0}
\foreach \X [remember=\mysum as \mysum] in {0,...,\mydim}
{\pgfmathsetmacro{\mypercentage}{{\LstNums}[\X]/\mytotal}
\pgfmathsetmacro{\mycolor}{{\LstColors}[\X]}
\begin{scope}[on background layer]
\draw[visible on=<\the\numexpr\istart+1+\X\relax->,fill=\mycolor]
(0,0) -- (\mysum:R) arc(\mysum:\mysum+\mypercentage*360:R) --cycle;
\end{scope}
\convertdirectly[cmy]{\mycolor}{\currhsb}
\pgfmathsetmacro{\currc}{1-{\currhsb}[0]}
\pgfmathsetmacro{\currm}{1-{\currhsb}[1]}
\pgfmathsetmacro{\curry}{1-{\currhsb}[2]}
\definecolor{tmp}{cmy}{\currc,\currm,\curry}
\draw[visible on=<\the\numexpr\istart+1+\X\relax->,color=tmp,thick]
(\mysum:0.2*R) arc(\mysum:\mysum+\mypercentage*360:0.2*R)
node[midway,circle,inner sep=1pt,anchor=180+\mysum+\mypercentage*180]
{$\pgfmathparse{int(360*\mypercentage+0.5)}\pgfmathresult^\circ$};
\pgfmathsetmacro{\mysum}{\mysum+{\LstNums}[\X]*360/\mytotal}
}
\end{tikzpicture}
\end{center}
\end{frame}
\end{document}
Здесь я использовал cmy
цветовую модель. Конечно, вполне возможно, что есть и лучшие отображения, чем x\mapsto 1-x
для x\in\{c,m,y\}
. Но результат, ИМХО, вполне читаемый.