TikZ-Roulette:让动画更逼真

TikZ-Roulette:让动画更逼真

考虑以下 MWE:

\documentclass[tikz]{standalone}
\usetikzlibrary{backgrounds}
\definecolor{filz}{RGB}{56,114,73}
%\pagecolor{filz}
\newcommand{\roulette}[1]{
%   \pgfmathsetseed{3}
    \pgfmathsetmacro\random{10*random(0,36)}
    \foreach \n in {0,10,...,\random}
%   \foreach \n in {\random,...,\random}
    {
        \begin{tikzpicture}
            \useasboundingbox (-.5,-.75) rectangle (3.5,2.75);

                \begin{scope}[scale=.25,shift={(-2,10)}]
                    \foreach \x in {1,...,3}
                    \foreach \y in {1,...,12}
                    {
                        \pgfmathsetmacro\number{int(\x+3*(\y-1))} 
                        \pgfmathsetmacro\testnumber{int(mod(\number,2))}

                        \ifnum\testnumber=0
                            \node[scale=.25,text=white,fill=red,minimum height=1.01cm,minimum width=1.01cm] at (\x,-\y) {\Huge\number};
                        \else
                            \node[scale=.25,text=white,fill,minimum height=1.01cm,minimum width=1.01cm] at (\x,-\y) {\Huge\number};
                        \fi
                    }

                    \node[scale=.25,text=white,fill=red,minimum height=1.01cm,minimum width=3.01cm] at (2,0) {\Huge 0};

                    \pgfmathsetmacro\testing{#1}
                    \pgfmathsetmacro\secure{int(mod(int(\testing),3))}

                    \ifnum\secure=0
                        \pgfmathsetmacro\xpos{mod(\testing,3)+3}
                        \pgfmathsetmacro\ypos{-int(\testing/3)}
                    \else
                        \pgfmathsetmacro\xpos{mod(\testing,3)}
                        \pgfmathsetmacro\ypos{-int(\testing/3)-1}
                    \fi

                    \ifnum#1>0
                    \pgfmathsetmacro\anothertest{int(mod(#1,2))}
                    \ifnum\anothertest=0
                        \draw[black,thick,fill=red] (\xpos,\ypos) circle(.2);
                    \else
                        \draw[red,thick,fill=black] (\xpos,\ypos) circle(.2);
                    \fi
                    \else
                        \draw[black,thick,fill=red] (1,0) circle(.2);
                    \fi
                \end{scope}

                \begin{scope}[shift={(2,1)}]
                    \foreach[count=\xx] \x in {0,20,...,340}
                    {
                        \fill[red] (\x:1) arc(\x:\x+10:1) -- (\x+10:.75) arc(\x+10:\x:.75) -- cycle;
                        \fill[rotate=10] (\x:1) arc(\x:\x+10:1) -- (\x+10:.75) arc(\x+10:\x:.75) -- cycle;
                            \draw[fill=white] (\x:1) arc(\x:\x+10:1) -- (\x+10:1.25) arc(\x+10:\x:1.25) -- cycle;
                            \draw[fill=white,rotate=10] (\x:1) arc(\x:\x+10:1) -- (\x+10:1.25) arc(\x+10:\x:1.25) -- cycle;
                    \pgfmathsetmacro\nn{int(2*(\xx-1))}
                        \pgfmathsetmacro\nnn{int(2*\xx-1)}
                            \node[red,rotate=\x,scale=.5] at (\x+5:1.1) {\nn};
                            \node[scale=.5,rotate=\x+15] at (\x+15:1.1) {\nnn};
                    }
                    \fill[ball color=white] (\n+5:{1-.05-(((1-2*.05)-.75)/2)}) circle(.05);
                \end{scope}

                \begin{pgfonlayer}{background}
                    \fill[filz] (current bounding box.south west) rectangle (current bounding box.north east);
                \end{pgfonlayer}
        \end{tikzpicture}
    }
}

\begin{document}
    \roulette{0}
\end{document}

输出如下:

在此处输入图片描述

我知道数字的顺序不正确,并且缺少一个数字,但这并不重要。我的问题是:

如何实现轮盘片顺时针旋转,而球逆时针旋转,当球落入格子时,两者都停止旋转。旋转应该与现实生活中一样,即开始时旋转速度比结束时快。

答案1

我采用了与@samcarter 的并假设角速度从某个最大值线性减小vmax到零。然后我对角速度进行积分以得到一个角度。抱歉,我不得不稍微缩短你的代码以生成可以上传的 gif。不幸的是,我不知道如何上传 mp4 文件,可以按照@samcarter 的另一个答案

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\pgfmathsetmacro{\Frame}{0}
\tikzset{declare function={tmax=100;
vmax=40;
rot(\t)=(\t/2)*(2-\t/tmax)*vmax;}}
\foreach \Frame in {0,...,100}
{\begin{tikzpicture}
\foreach \Y [evaluate=\Y as \X using {10*\Y+rot(\Frame)}] in {0,...,35}
{
\ifodd\Y
\fill (\X-5:2.5) -- (\X-5:2) arc(\X-5:\X+5:2) -- (\X+5:2.5) arc(\X+5:\X-5:2.5);
\node[rotate=\X] at (\X:2.75){\Y};
\else
\fill[red] (\X-5:2.5) -- (\X-5:2) arc(\X-5:\X+5:2) -- (\X+5:2.5) arc(\X+5:\X-5:2.5);
\node[rotate=\X,red] at (\X:2.75){\Y};
\fi
\draw (\X-5:2.5) -- (\X-5:3) arc(\X-5:\X+5:3) 
-- (\X+5:2.5) arc(\X+5:\X-5:2.5);
}
\shade[ball color=gray] ({-rot(\Frame)}:2.25) circle (1mm);
\end{tikzpicture}}
\end{document}

在此处输入图片描述

答案2

对于你问题中关于减速的部分:

一个简单的解决方案是编写一个包装文档,以递增的次数显示动画的每一页。

例如,如果您的动画创建了 16 页,则以下文档将显示第一页一次,第二页两次等。您也可以使用其他函数,此线性函数仅为示例:

\documentclass{beamer}

\setbeamertemplate{navigation symbols}{}
\usepackage{tikz}

\definecolor{filz}{RGB}{56,114,73}
\setbeamercolor{background canvas}{bg=filz}

\begin{document}

\foreach \n in {1,...,16}{

\begin{frame}[plain]
\foreach \x in {1,...,\insertframenumber}{
\includegraphics<+>[height=\paperheight,page=\insertframenumber]{document}}
\end{frame}

}

\end{document}

在此处输入图片描述

(抱歉图片太小,否则 .gif 太大无法上传)

相关内容