TikZ 是否支持交互式动画?

TikZ 是否支持交互式动画?

我正在绘制一个函数y = a*x^2,其中 a 是变量常数。我想以交互方式控制 a,但我谷歌了一下,似乎 TikZ 不支持交互式操作。

另外,我想知道是否有任何方法可以在函数内绘制一些点并随机移动?

答案1

实际上,恕我直言,这可以看作是两个不同的问题。

那么,让我们从第一个开始:

我正在绘制一个函数y = a*x^2,其中 a 是变量常数。我想以交互方式控制 a,但我谷歌了一下,似乎 TikZ 不支持交互式操作。

我会用这个奇妙的ocgx包装与pgfplots;在网站上你已经可以找到一些例子:

代码:

\documentclass{article}

\usepackage{pgfplots}
\usetikzlibrary{ocgx}
\tikzset{ocg button/.style={circle,inner sep=.25em,switch ocg with mark on={#1}{}}}
\tikzset{base/.style={baseline=-0.5ex}}

\newcommand{\function}{\x^2}
\newcommand{\button}[2]{\tikz[base]\node[fill=#2!30,ocg button=#1]{};}
\newcommand{\plotit}[2]{\addplot+[ocg={name=#2,ref=#2}]{#1};\label{#2}}
\newcommand{\legendit}[3]{\item[\ref{#1}] #2$x^2$ \button{#1}{#3}}


\begin{document}
\begin{minipage}[b][0.4\textheight][l]{0.7\textwidth}
\begin{tikzpicture}
\begin{axis}[grid= major,xlabel=$x$, 
  ylabel =$y$, 
  ylabel style={rotate=-90},
  cycle list={blue,red,green!50!lime,orange,cyan!50!blue},
  ]
 \plotit{\function}{first}
 \plotit{1.5*\function}{second}
 \plotit{2.25*\function}{third}
 \plotit{3*\function}{fourth}
 \plotit{5*\function}{fifth}
\end{axis}
\end{tikzpicture}
\end{minipage}%
\begin{minipage}[b][0.5\textheight][c]{0.2\textwidth}
\begin{itemize}
\legendit{first}{}{blue}
\legendit{second}{1.5}{red}
\legendit{third}{2.25}{green!50!lime}
\legendit{fourth}{3}{orange}
\legendit{fifth}{5}{cyan!50!blue}
\end{itemize}
\end{minipage}%

\end{document}​

结果(点击第二和第四个按钮):

在此处输入图片描述

免责声明

这对我来说在 Evince(Ubuntu 12.10 附带的标准版本)和 Acrobat Reader 下有效。

现在我们来谈谈第二个问题:

另外,我想知道是否有任何方法可以在函数内绘制一些点并随机移动?

为此,我将使用standalone带有选项的类tikz,并按顺序将点沿着图放置,并带有设施

node[<some opitons>, pos=<position along the plot>]

其中<position along the plot>应该是 0 到 1 之间的某个数字。

一个例子:

\documentclass[tikz]{standalone}
\usepackage{pgfplots}


\begin{document}
\foreach \pos in {0,0.05,...,1.05}{
\begin{tikzpicture}
\begin{axis}[grid= major,xlabel=$x$, 
  ylabel =$y$, 
  ylabel style={rotate=-90},
  no marks,
  ]
  
 \addplot{\x^2}
    node[fill=orange,draw=blue,circle,inner sep=1pt, pos=\pos]{}
  ;
\end{axis}
\end{tikzpicture}
}
\end{document}

结果:

在此处输入图片描述

如果你想要随机点,只需更改里面的列表

\foreach \pos in {0,0.05,...,1.05}

其中改变我的意思是你必须打乱顺序(为了简单起见我没有这样做)。

一条注释:列表以 结束1.05,但未1正确显示最终点。


要在图中拥有随机点,基本上有两种方法:第一种方法是通过独立类(在以下答案中有几个例子使用 TikZ 绘制封闭的液滴形曲线),而第二个利用 Beamer 类;其样式定义在使用 TikZ 节点在 Beamer 中突出显示可以根据某些节点出现的时刻来定位它们:这会产生一种随机性。

代码:

\documentclass{beamer}
\usepackage{lmodern}
\usepackage{pgfplots}


\tikzset{
    invisible/.style={opacity=0,text opacity=0},
    visible on/.style={alt=#1{}{invisible}},
    alt/.code args={<#1>#2#3}{%
      \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} 
    },
}

% https://tex.stackexchange.com/questions/84513/highlighting-in-beamer-using-tikz-nodes/84608#84608
\tikzset{
  background filldraw/.style args={#1 and #2}{draw=#1, fill=#2},
  background filldraw/.default={white and white},
  filldraw on/.style={alt=#1{}{background filldraw}},
}

\begin{document}
\begin{frame}{}
\begin{tikzpicture}
\begin{axis}[grid= major,xlabel=$x$, 
  ylabel =$y$, 
  ylabel style={rotate=-90},
  no marks,
  ]

 \addplot{\x^2};
    
\end{axis}
\foreach \pos/\moment in {{(4,4)}/{1,3,5,6},{(2,2)}/{2,3,4,8},
 {(1.5,4)}/{2,4,5,7},{(5,3)}/{1,2,3,5,8},{(2.5,1.5)}/{2,4,5,6},
 {(1.75,3.5)}/{1,3,6,8},{(3.75,2.5)}/{2,5,7,8},{(3.75,1.25)}/{2,3,4,5,6}}{
 \node[circle, inner sep=1.5pt,
   background filldraw={blue and orange},
   filldraw on=<\moment>] at \pos {};
}
\end{tikzpicture}
\end{frame}
\end{document}

结果:

在此处输入图片描述

答案2

在此处输入图片描述

真正的交互性(即您可以顺利修改绘制函数的参数)超出了 PDF 标准的可能性。但是,PDF 标准允许将交互元素嵌入文档中,即 RichMedia Annotation,它将显示和用户交互委托给插件。目前只有 Adob​​eReader 实现了 RichMedia Annotation,它使用 FlashPlayer 来渲染注释区域内的图形材料。

因此,交互式应用程序必须采用 Flash (SWF) 格式。例如,可以使用现在开源的Flex-SDK. 生成的 SWF 可以使用 media9 包嵌入到 PDF 中。

该示例使用了 Flex 的 LineChart 和 HSlider 组件。

\documentclass[12pt]{article}
\usepackage{media9}

\begin{document}

\section{Interactive function plot example}

\begin{equation}
y=a x^2
\end{equation}

\noindent\includemedia[
  width=\linewidth,height=1.1\linewidth,
  activate=pageopen
]{}{bec.swf}
\end{document}

嵌入的 Flash 文件bec.swf(按照主题发布者的要求,可视化类似于 Bose-Einstein 凝聚态的东西)是使用Flex-SDK 中的编译器从bec.mxml下面列出的Flex 源文件编译而来的。mxmlc

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
  initialize="init();">

  <mx:Script><![CDATA[
  import mx.collections.ArrayCollection;
  import flash.utils.Timer;
  import flash.events.TimerEvent;

  [Bindable] private var quadFunc:ArrayCollection = new ArrayCollection();
  [Bindable] private var atoms:ArrayCollection = new ArrayCollection();
  private var xMax:Number=10;
  private var yMax:Number=300;
  private var updateTimer:Timer;

  public function atomPositions(e:TimerEvent):void {
    atoms.removeAll();
    var yM:Number=aSlider.value*xMax*xMax;

    for (var i:Number = 0; i<50; i++){
      var y:Number=Math.random()*yM;
      var x:Number=(Math.random()*2-1)*Math.sqrt(y/aSlider.value);
      atoms.addItem({xPos:x, yPos:y});
    }
  }

  public function change():void {
    quadFunc.removeAll();
    for (var i:Number = -xMax; i<=xMax; i+=0.1){
      var yVal:Number=aSlider.value*i*i;
      quadFunc.addItem({xVal:i, yVal:yVal});
    }
    atomPositions(null);
  }

  public function init():void {
    haxis.minimum=-xMax;
    haxis.maximum=xMax;
    vaxis.maximum=yMax;

    change();
    updateTimer = new Timer(50,0);
    updateTimer.addEventListener("timer", atomPositions);
    updateTimer.start();
  }
  ]]></mx:Script>

  <mx:LineChart id="chart" width="100%" height="100%"
     showDataTips="true">
     <mx:horizontalAxis>
         <mx:LinearAxis id="haxis"/>
     </mx:horizontalAxis>
     <mx:verticalAxis>
         <mx:LinearAxis id="vaxis" minimum="-2"/>
     </mx:verticalAxis>
     <mx:series>
        <mx:LineSeries xField="xVal" yField="yVal" form="curve"
           dataProvider="{quadFunc}"/>
        <mx:PlotSeries xField="xPos" yField="yPos" dataProvider="{atoms}"
           itemRenderer="mx.charts.renderers.CircleItemRenderer"/>
     </mx:series>
  </mx:LineChart>
  <mx:HSlider id="aSlider" width="100%"
    minimum="0.1" maximum="3" value="0.1"
    dataTipPlacement="top" 
    snapInterval="0.01" tickInterval="0"
    labels="[a=0.1,3]" 
    allowTrackClick="true" 
    liveDragging="true"
    change="change();"/>
</mx:Application>

相关内容