%% %% This is file `interactiveplot.sty', %% Copyright (C) 2014 by Roberto Bock, Javier Toro, Pedro Linares %% This file may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either %% version 1.2 of this license or (at your option) any later %% version. The latest version of this license is in: %% http://www.latex-project.org/lppl.txt %% and version 1.2 or later is part of all distributions of %% LaTeX version 1999/12/01 or later. \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{interactiveplot} [ 2014/09/20 v1.2] \RequirePackage{datetime} \RequirePackage{xstring} \RequirePackage{stack} \RequirePackage{ifthen} \RequirePackage{forloop} \RequirePackage{calc} \RequirePackage{etoolbox} \ifdef{\StrCut}{} {% \long\def\@xs@ifempty#1{% \expandafter\ifx\expandafter\relax\detokenize{#1}\relax \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } \@xs@newmacro*3\StrCut{1}{2}{0}{% \@xs@ifempty{#3}% {\global\let\groupID\@empty \let\@xs@reserved@C\@empty \let\@xs@reserved@E\@empty } {\ifnum#1<\@ne\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi {\@xs@StrCut@ii{#2}{#3}1} {\@xs@StrCut@ii{#2}{#3}{#1}}% }% \@xs@StrCut@iii } \long\def\@xs@StrCut@ii#1#2#3{% \def\@xs@reserved@D{#1}% \let\@xs@reserved@C\@empty \def\@xs@reserved@E{#2}% \decimalpart\z@\integerpart\z@ \gdef\groupID{0}% \let\@xs@nestlevel\z@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\expandafter{\@xs@reserved@C}}% \@xs@read@reserved@D }% \def\@xs@atoccurfound{% \ifnum\decimalpart=\numexpr(#3)\relax \global\let\@xs@reserved@D\@xs@reserved@D \global\let\@xs@reserved@C\@xs@reserved@C \@xs@exitallgroups \let\@xs@next\relax \else \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\@xs@reserved@E}% \let\@xs@next\@xs@read@reserved@D \fi }% \@xs@read@reserved@D \def\@xs@argument@A{#2}% \let\@xs@reserved@E\@xs@reserved@D \expandafter\expandafter\expandafter \def \expandafter\expandafter\expandafter \@xs@reserved@D \expandafter\expandafter\expandafter {\expandafter\@xs@reserved@C\@xs@argument@A}% } \long\def\@xs@StrCut@iii#1#2{\let#1\@xs@reserved@C\let#2\@xs@reserved@E} } %% This macro includes an object inside a PDF \newcommand{\interactiveplot@insertobj}[2]{ \immediate\pdfobj{#2}% \expandafter\edef \csname #1\endcsname {\the\pdflastobj} } %% This macro makes a reference to an object by its name \newcommand{\interactiveplot@oref}[1]{ \csname #1\endcsname\space 0 R } %% this macro define a Button, this button is used to \newcommand{\interactiveplot@plotbuttoncaption}[2]{ \newdimen\textw \newdimen\texth \settowidth{\textw}{#2} \settoheight{\texth}{#2} \hbox{\pdfstartlink width \textw height \texth user{ %% pdfstartlink defines an annotation /Subtype /Widget /FT /Btn /F 2 %%this line defines the annotation of type Widget, /FT means the kind of widget is /Btn (i.e pushButton), /F is especially important because it defines that this annotation is hidden /Ff 65537 /T (Button#1)%% /Ff defienes the type of button this property means that button is non-interactive, /T defines its tittle /BS << /W 0 /S /S >> %% /BS is a dictionary that defines the border Style of this annotation, /W defines the border width in points, /S defines the border Style and the subsecuent /S means solid i.e the border Style is Solid /MK << /BG [1] /CA (#2) >> %% /MK defines a appareance characteristics, /BG defines the widget background, and /CA defines the caption text of the button /H /P %% /H is the annotation Higlighting mode, the visual effect to be used when the mouse button is pressed, /P in this case the value of /H is /P that the means the Hightlighting visual effect aspect is like a down push button appareance }\hfil\strut\pdfendlink}\vskip-\baselineskip} %% This macro defines a button, this button is not interactive for the user, it display a button without background but it has caption and shows to user the function that is plotted \newcommand{\interactiveplot@functionbutton}[2]{ \newdimen\textw \newdimen\texth \settowidth{\textw}{#2} \settoheight{\texth}{#2} \hbox{\pdfstartlink width \textw height \texth user{ /Subtype /Widget /FT /Btn /F 2 /Ff 65537 /T (buttonFunctionCaption#1) /BS << /W 0 /S /S >> /MK << /BG [1] /CA (#2) >> /H /P }\hfil\strut\pdfendlink}\vskip-\baselineskip} %% This macro insert in a PDF an annotation of kind textfield in where the actual value of a parameter is shown \newcommand{\interactiveplot@fieldparamvalue}[1]{ \newdimen\textw \newdimen\texth \settowidth{\textw}{#1} \settoheight{\texth}{#1} \hbox{\pdfstartlink width \textw height \texth user{ /Subtype /Widget /FT /Tx /T (Field#1) /BS << /W 1 /S /B >>%% /W 1 defines the border width in 1, and /S /B defines the border line in Beveled /MK << /BG [1] >> /H /P }\hfil\strut\pdfendlink}\vskip -\baselineskip} %% This macro insert in a PDF a button with predefined caption in "-" or "+" \newcommand{\interactiveplot@plotbutton}[2]{ \ifthenelse{\equal{#2}{minus}}{\xdef\simbolaction{-}}{\xdef\simbolaction{+}} \hbox to .5cm{\pdfstartlink height 10pt user{ /Subtype /Widget /FT /Btn /F 2 /Ff 65536 /T (Button#1#2) /BS << /W 1 /S /B >> /MK << /BG [0.8] /CA (\simbolaction) >> /H /P }\hfil\strut\pdfendlink}\vskip-\baselineskip} %%This macro insert in a PDF a Button, this button is used to be upside all other annotations (axis, graphic, etc) and get all the clicks envenoms on it prevent the other annotations get the events on their \newcommand{\interactiveplot@square}[1]{ \hbox to 1cm{\pdfstartlink user{ /Subtype /Widget /FT /Btn %/F 6 /Ff 65537 /T (squareUbication#1) /BS << /W 0 /S /B >> /MK << /BG [1] /CA () >> /H /N }\hfil\strut\pdfendlink } \hbox {\pdfstartlink user{ /Subtype /Widget /FT /Btn %/F 6 /Ff 65537 /T (square#1) /BS << /W 0 /S /B >> /MK << /BG [1] /CA () >> /H /N }\hfil\strut\pdfendlink } } %%this macro inserts in a PDF the AcroForm object who allows us use interactive properties of PDF \interactiveplot@insertobj{Helv}{ << /Type /Font /Subtype /Type1 /Name /Helv /BaseFont /Helvetica >> } \interactiveplot@insertobj{AcroForm}{ << /DR << /Font << /Helv \interactiveplot@oref{Helv} >> >> /DA (/Helv 9 Tf 0 g ) /NeedAppearances true >> } \pdfcatalog{/AcroForm \interactiveplot@oref{AcroForm}} %%the counters are initialized, in this package all the functions are managed by index \newcount\interactiveplot@functions\interactiveplot@functions=0 \newlength{\interactiveplot@CompletenaturalIplotHeight} \xdef\interactiveplot@ecuationJS{}%In this macro is stored all the javascript code builded in all the procces of do an interactive plot \xdef\interactiveplot@buttonsmanage{}%In this macro are stored all the Buttons Data (the buttons who change the parameters values) \def\interactiveplot@isOperator#1[#2]{%This macro compare if an input is an operator \xdef\interactiveplot@val{#1} \ifthenelse{\equal{\interactiveplot@val}{+}\OR\equal{\interactiveplot@val}{(}\OR\equal{\interactiveplot@val}{)}\OR\equal{\interactiveplot@val}{/}\OR\equal{\interactiveplot@val}{\string^}\OR\equal{\interactiveplot@val}{*}\OR\equal{\interactiveplot@val}{-}\OR\equal{\interactiveplot@val}{ sin}\OR\equal{\interactiveplot@val}{ cos}\OR\equal{\interactiveplot@val}{ tan}\OR\equal{\interactiveplot@val}{ sec}\OR\equal{\interactiveplot@val}{ csc}\OR\equal{\interactiveplot@val}{ cot}\OR\equal{\interactiveplot@val}{ asin}\OR\equal{\interactiveplot@val}{ acos}\OR\equal{\interactiveplot@val}{ atan}\OR\equal{\interactiveplot@val}{ asec}\OR\equal{\interactiveplot@val}{ acsc}\OR\equal{\interactiveplot@val}{ acot}\OR\equal{\interactiveplot@val}{ sinh}\OR\equal{\interactiveplot@val}{ cosh}\OR\equal{\interactiveplot@val}{ tanh}\OR\equal{\interactiveplot@val}{ sech}\OR\equal{\interactiveplot@val}{ csch}\OR\equal{\interactiveplot@val}{ coth}\OR\equal{\interactiveplot@val}{ asinh}\OR\equal{\interactiveplot@val}{ acosh}\OR\equal{\interactiveplot@val}{ atanh}\OR\equal{\interactiveplot@val}{ asech}\OR\equal{\interactiveplot@val}{ acsch}\OR\equal{\interactiveplot@val}{ acoth}\OR\equal{\interactiveplot@val}{ ln}\OR\equal{\interactiveplot@val}{ exp}\OR\equal{\interactiveplot@val}{ log}} { \expandafter\xdef\csname #2\endcsname{1} }{ \expandafter\xdef\csname #2\endcsname{0} } } %%this macro validate the precedences of the operators, i.e. when you write 2+2*8 it will do 2*8 first and them (2*8)+2 that is 18, the operator * is first and precedes the operator + %%Now precedence in stack is used because when you are using stacks to parse the function the precedence will be a little bit different than if an operator is out of the stack \def\interactiveplot@PrecedenceInStack#1[#2]{ \xdef\interactiveplot@out{0} \xdef\interactiveplot@val{#1} \ifthenelse{\equal{\interactiveplot@val}{(}\OR\equal{\interactiveplot@val}{)}}{ \xdef\interactiveplot@out{0} }{} \ifthenelse{\equal{\interactiveplot@val}{*}\OR\equal{\interactiveplot@val}{/}}{ \xdef\interactiveplot@out{2} }{} \ifthenelse{\equal{\interactiveplot@val}{\string^}\OR\equal{\interactiveplot@val}{ sqrt}}{ \xdef\interactiveplot@out{3} }{} \ifthenelse{\equal{\interactiveplot@val}{+}\OR\equal{\interactiveplot@val}{-}}{ \xdef\interactiveplot@out{1} }{} \ifthenelse{\equal{\interactiveplot@val}{ sin}\OR\equal{\interactiveplot@val}{ cos}\OR\equal{\interactiveplot@val}{ tan}\OR\equal{\interactiveplot@val}{ sec}\OR\equal{\interactiveplot@val}{ csc}\OR\equal{\interactiveplot@val}{ cot}\OR\equal{\interactiveplot@val}{ asin}\OR\equal{\interactiveplot@val}{ acos}\OR\equal{\interactiveplot@val}{ atan}\OR\equal{\interactiveplot@val}{ asec}\OR\equal{\interactiveplot@val}{ acsc}\OR\equal{\interactiveplot@val}{ acot}\OR\equal{\interactiveplot@val}{ sinh}\OR\equal{\interactiveplot@val}{ cosh}\OR\equal{\interactiveplot@val}{ tanh}\OR\equal{\interactiveplot@val}{ sech}\OR\equal{\interactiveplot@val}{ csch}\OR\equal{\interactiveplot@val}{ coth}\OR\equal{\interactiveplot@val}{ asinh}\OR\equal{\interactiveplot@val}{ acosh}\OR\equal{\interactiveplot@val}{ atanh}\OR\equal{\interactiveplot@val}{ asech}\OR\equal{\interactiveplot@val}{ acsch}\OR\equal{\interactiveplot@val}{ acoth}\OR\equal{\interactiveplot@val}{ ln}\OR\equal{\interactiveplot@val}{ exp}\OR\equal{\interactiveplot@val}{ log}}{ \xdef\interactiveplot@out{4} }{} \expandafter\xdef\csname #2\endcsname{\interactiveplot@out} } %%this macro validate the precedence of operators, you can obtain information about this info in wikipedia \def\interactiveplot@Precedence#1[#2]{ \xdef\interactiveplot@out{0} \xdef\val{#1} \ifthenelse{\equal{\val}{(}\OR\equal{\val}{)}}{ \xdef\interactiveplot@out{5} }{} \ifthenelse{\equal{\val}{*}\OR\equal{\val}{/}}{ \xdef\interactiveplot@out{2} }{} \ifthenelse{\equal{\val}{\string^}\OR\equal{\val}{ sqrt}}{ \xdef\interactiveplot@out{3} }{} \ifthenelse{\equal{\val}{+}\OR\equal{\val}{-}}{ \xdef\interactiveplot@out{1} }{} \ifthenelse{\equal{\val}{ sin}\OR\equal{\val}{ cos}\OR\equal{\val}{ tan}\OR\equal{\val}{ sec}\OR\equal{\val}{ csc}\OR\equal{\val}{ cot}\OR\equal{\val}{ asin}\OR\equal{\val}{ acos}\OR\equal{\val}{ atan}\OR\equal{\val}{ asec}\OR\equal{\val}{ acsc}\OR\equal{\val}{ acot}\OR\equal{\val}{ sinh}\OR\equal{\val}{ cosh}\OR\equal{\val}{ tanh}\OR\equal{\val}{ sech}\OR\equal{\val}{ csch}\OR\equal{\val}{ coth}\OR\equal{\val}{ asinh}\OR\equal{\val}{ acosh}\OR\equal{\val}{ atanh}\OR\equal{\val}{ asech}\OR\equal{\val}{ acsch}\OR\equal{\val}{ acoth}\OR\equal{\val}{ ln}\OR\equal{\val}{ exp}\OR\equal{\val}{ log}}{ \xdef\interactiveplot@out{4} }{} \expandafter\xdef\csname #2\endcsname{\interactiveplot@out} } %%this verify if an operator is unary (look at wikipedia unary operators!) \def\interactiveplot@isUnary#1[#2]{ \xdef\val{#1} \ifthenelse{\equal{\val}{ sin}\OR\equal{\val}{ cos}\OR\equal{\val}{ tan}\OR\equal{\val}{ sec}\OR\equal{\val}{ csc}\OR\equal{\val}{ cot}\OR\equal{\val}{ asin}\OR\equal{\val}{ acos}\OR\equal{\val}{ atan}\OR\equal{\val}{ asec}\OR\equal{\val}{ acsc}\OR\equal{\val}{ acot}\OR\equal{\val}{ sinh}\OR\equal{\val}{ cosh}\OR\equal{\val}{ tanh}\OR\equal{\val}{ sech}\OR\equal{\val}{ csch}\OR\equal{\val}{ coth}\OR\equal{\val}{ asinh}\OR\equal{\val}{ acosh}\OR\equal{\val}{ atanh}\OR\equal{\val}{ asech}\OR\equal{\val}{ acsch}\OR\equal{\val}{ acoth}\OR\equal{\val}{ ln}\OR\equal{\val}{ exp}\OR\equal{\val}{ log}} { \expandafter\xdef\csname #2\endcsname{1} }{ \expandafter\xdef\csname #2\endcsname{0} } } %%this macro convert the functions operators from the natural language to javascript language \def\interactiveplot@FJS#1[#2]{ \xdef\val{#1} \xdef\interactiveplot@out{} \ifthenelse{\equal{\val}{ sin}}{ \edef\interactiveplot@out{Math.sin}}{} \ifthenelse{\equal{\val}{ asin}}{ \edef\interactiveplot@out{Math.asin}}{} \ifthenelse{\equal{\val}{ cos}}{ \edef\interactiveplot@out{Math.cos}}{} \ifthenelse{\equal{\val}{ acos}}{ \edef\interactiveplot@out{Math.acos}}{} \ifthenelse{\equal{\val}{ tan}}{ \edef\interactiveplot@out{Math.tan}}{} \ifthenelse{\equal{\val}{ atan}}{ \edef\interactiveplot@out{Math.atan}}{} \ifthenelse{\equal{\val}{ csc}}{ \edef\interactiveplot@out{1/Math.sin}}{} \ifthenelse{\equal{\val}{ acsc}}{ \edef\interactiveplot@out{acsc}}{} \ifthenelse{\equal{\val}{ sec}}{ \edef\interactiveplot@out{1/Math.cos}}{} \ifthenelse{\equal{\val}{ asec}}{ \edef\interactiveplot@out{asec}}{} \ifthenelse{\equal{\val}{ cot}}{ \edef\interactiveplot@out{1/Math.tan}}{} \ifthenelse{\equal{\val}{ acot}}{ \edef\interactiveplot@out{acot}}{} \ifthenelse{\equal{\val}{ sinh}}{ \edef\interactiveplot@out{sinh}}{} \ifthenelse{\equal{\val}{ asinh}}{ \edef\interactiveplot@out{asinh}}{} \ifthenelse{\equal{\val}{ cosh}}{ \edef\interactiveplot@out{cosh}}{} \ifthenelse{\equal{\val}{ acosh}}{ \edef\interactiveplot@out{acosh}}{} \ifthenelse{\equal{\val}{ coth}}{ \edef\interactiveplot@out{coth}}{} \ifthenelse{\equal{\val}{ acoth}}{ \edef\interactiveplot@out{acoth}}{} \ifthenelse{\equal{\val}{ tanh}}{ \edef\interactiveplot@out{tanh}}{} \ifthenelse{\equal{\val}{ atanh}}{ \edef\interactiveplot@out{atanh}}{} \ifthenelse{\equal{\val}{ csch}}{ \edef\interactiveplot@out{csch}}{} \ifthenelse{\equal{\val}{ acsch}}{ \edef\interactiveplot@out{acsch}}{} \ifthenelse{\equal{\val}{ sech}}{ \edef\interactiveplot@out{sech}}{} \ifthenelse{\equal{\val}{ asech}}{ \edef\interactiveplot@out{asech}}{} \ifthenelse{\equal{\val}{ exp}}{ \edef\interactiveplot@out{Math.exp}}{} \ifthenelse{\equal{\val}{ sqrt}}{ \edef\interactiveplot@out{Math.sqrt}}{} \ifthenelse{\equal{\val}{ ln}}{ \edef\interactiveplot@out{Math.ln}}{} \ifthenelse{\equal{\val}{ log}}{ \edef\interactiveplot@out{Math.log}}{} \ifthenelse{\equal{\val}{ frac}}{ \edef\interactiveplot@out{/}}{} \ifthenelse{\equal{\val}{\string^}}{ \edef\interactiveplot@out{Math.pow}}{} \expandafter\xdef\csname #2\endcsname{\interactiveplot@out} } %%this macro verify if an input is a decimal number \def\interactiveplot@isDecimal#1[#2]{ \IfDecimal{#1}{\edef\decimalaux{1}}{\edef\decimalaux{0}} \expandafter\xdef\csname #2\endcsname{\decimalaux} } %%this macro verify if an input is a variable \def\interactiveplot@isVariable#1[#2]{ \ifx\interactiveplot@variablelist\undefined \xdef\interactiveplot@parameterlist{} \fi \IfSubStr{\interactiveplot@variablelist}{#1}{\edef\interactiveplot@variableaux{1}}{\edef\interactiveplot@variableaux{0}} \expandafter\xdef\csname #2\endcsname{\interactiveplot@variableaux} } %%this macro verify if an input is a parameter \def\interactiveplot@isParameter#1[#2]{ \ifx\interactiveplot@parameterlist\undefined \xdef\interactiveplot@parameterlist{} \fi \IfSubStr{\interactiveplot@parameterlist}{#1}{\edef\interactiveplot@parameteraux{1}}{\edef\interactiveplot@parameteraux{0}} \expandafter\xdef\csname #2\endcsname{\interactiveplot@parameteraux} } %%this macro verify if the unary operator is different to a trigonometric function operator \def\Special#1[#2]{ \xdef\val{#1} \ifthenelse{\equal{\val}{ sqrt}\OR\equal{\val}{ exp}\OR\equal{\val}{\string^}} { \expandafter\xdef\csname #2\endcsname{1} }{ \expandafter\xdef\csname #2\endcsname{0} } } \newcounter{auxverifunari} %%This macro compare if an input is an operator, if it is a unary parameter it appends a whitespace at the beginning, i do this because in first instance the function could be disordered and them it will be ordered \def\interactiveplot@verifUnariFunc#1[#2]{ \edef\interactiveplot@output{#1} \IfSubStr{\interactiveplot@output}{sin(}{\StrPosition{\interactiveplot@output}{sin(}[\interactiveplot@position]\ifthenelse{\interactiveplot@position=0}{\StrSubstitute{\interactiveplot@output}{sin(}{ sin(}[\interactiveplot@output]}{\StrPosition{\interactiveplot@output}{a}[\arcposition]\setcounter{auxverifunari}{\interactiveplot@position}\addtocounter{auxverifunari}{-1}\ifthenelse{\value{auxverifunari}>0\AND\value{auxverifunari}=\arcposition}{}{\StrSubstitute{\interactiveplot@output}{sin(}{ sin(}[\interactiveplot@output]}}}{} \IfSubStr{\interactiveplot@output}{cos(}{\StrPosition{\interactiveplot@output}{cos(}[\interactiveplot@position]\ifthenelse{\interactiveplot@position=0}{\StrSubstitute{\interactiveplot@output}{cos(}{ cos(}[\interactiveplot@output]}{\StrPosition{\interactiveplot@output}{a}[\arcposition]\setcounter{auxverifunari}{\interactiveplot@position}\addtocounter{auxverifunari}{-1}\ifthenelse{\value{auxverifunari}>0\AND\value{auxverifunari}=\arcposition}{}{\StrSubstitute{\interactiveplot@output}{cos(}{ cos(}[\interactiveplot@output]}}}{} \IfSubStr{\interactiveplot@output}{tan(}{\StrPosition{\interactiveplot@output}{tan(}[\interactiveplot@position]\ifthenelse{\interactiveplot@position=0}{\StrSubstitute{\interactiveplot@output}{tan(}{ tan(}[\interactiveplot@output]}{\StrPosition{\interactiveplot@output}{a}[\arcposition]\setcounter{auxverifunari}{\interactiveplot@position}\addtocounter{auxverifunari}{-1}\ifthenelse{\value{auxverifunari}>0\AND\value{auxverifunari}=\arcposition}{}{\StrSubstitute{\interactiveplot@output}{tan(}{ tan(}[\interactiveplot@output]}}}{} \IfSubStr{\interactiveplot@output}{cot(}{\StrPosition{\interactiveplot@output}{cot(}[\interactiveplot@position]\ifthenelse{\interactiveplot@position=0}{\StrSubstitute{\interactiveplot@output}{cot(}{ cot(}[\interactiveplot@output]}{\StrPosition{\interactiveplot@output}{a}[\arcposition]\setcounter{auxverifunari}{\interactiveplot@position}\addtocounter{auxverifunari}{-1}\ifthenelse{\value{auxverifunari}>0\AND\value{auxverifunari}=\arcposition}{}{\StrSubstitute{\interactiveplot@output}{cot(}{ cot(}[\interactiveplot@output]}}}{} \IfSubStr{\interactiveplot@output}{csc(}{\StrPosition{\interactiveplot@output}{csc(}[\interactiveplot@position]\ifthenelse{\interactiveplot@position=0}{\StrSubstitute{\interactiveplot@output}{csc(}{ csc(}[\interactiveplot@output]}{\StrPosition{\interactiveplot@output}{a}[\arcposition]\setcounter{auxverifunari}{\interactiveplot@position}\addtocounter{auxverifunari}{-1}\ifthenelse{\value{auxverifunari}>0\AND\value{auxverifunari}=\arcposition}{}{\StrSubstitute{\interactiveplot@output}{csc(}{ csc(}[\interactiveplot@output]}}}{} \IfSubStr{\interactiveplot@output}{sec(}{\StrPosition{\interactiveplot@output}{sec(}[\interactiveplot@position]\ifthenelse{\interactiveplot@position=0}{\StrSubstitute{\interactiveplot@output}{sec(}{ sec(}[\interactiveplot@output]}{\StrPosition{\interactiveplot@output}{a}[\arcposition]\setcounter{auxverifunari}{\interactiveplot@position}\addtocounter{auxverifunari}{-1}\ifthenelse{\value{auxverifunari}>0\AND\value{auxverifunari}=\arcposition}{}{\StrSubstitute{\interactiveplot@output}{sec(}{ sec(}[\interactiveplot@output]}}}{} \StrSubstitute{\interactiveplot@output}{asin(}{ asin(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{acos(}{ acos(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{atan(}{ atan(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{acot(}{ acot(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{asec(}{ asec(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{acsc(}{ acsc(}[\interactiveplot@output] \IfSubStr{\interactiveplot@output}{sinh(}{\StrPosition{\interactiveplot@output}{sinh(}[\interactiveplot@position]\ifthenelse{\interactiveplot@position=0}{\StrSubstitute{\interactiveplot@output}{sinh(}{ sinh(}[\interactiveplot@output]}{\StrPosition{\interactiveplot@output}{a}[\arcposition]\setcounter{auxverifunari}{\interactiveplot@position}\addtocounter{auxverifunari}{-1}\ifthenelse{\value{auxverifunari}>0\AND\value{auxverifunari}=\arcposition}{}{\StrSubstitute{\interactiveplot@output}{sinh(}{ sinh(}[\interactiveplot@output]}}}{} \IfSubStr{\interactiveplot@output}{cosh(}{\StrPosition{\interactiveplot@output}{cosh(}[\interactiveplot@position]\ifthenelse{\interactiveplot@position=0}{\StrSubstitute{\interactiveplot@output}{cosh(}{ cosh(}[\interactiveplot@output]}{\StrPosition{\interactiveplot@output}{a}[\arcposition]\setcounter{auxverifunari}{\interactiveplot@position}\addtocounter{auxverifunari}{-1}\ifthenelse{\value{auxverifunari}>0\AND\value{auxverifunari}=\arcposition}{}{\StrSubstitute{\interactiveplot@output}{cosh(}{ cosh(}[\interactiveplot@output]}}}{} \IfSubStr{\interactiveplot@output}{tanh(}{\StrPosition{\interactiveplot@output}{tanh(}[\interactiveplot@position]\ifthenelse{\interactiveplot@position=0}{\StrSubstitute{\interactiveplot@output}{tanh(}{ tanh(}[\interactiveplot@output]}{\StrPosition{\interactiveplot@output}{a}[\arcposition]\setcounter{auxverifunari}{\interactiveplot@position}\addtocounter{auxverifunari}{-1}\ifthenelse{\value{auxverifunari}>0\AND\value{auxverifunari}=\arcposition}{}{\StrSubstitute{\interactiveplot@output}{tanh(}{ tanh(}[\interactiveplot@output]}}}{} \IfSubStr{\interactiveplot@output}{coth(}{\StrPosition{\interactiveplot@output}{coth(}[\interactiveplot@position]\ifthenelse{\interactiveplot@position=0}{\StrSubstitute{\interactiveplot@output}{coth(}{ coth(}[\interactiveplot@output]}{\StrPosition{\interactiveplot@output}{a}[\arcposition]\setcounter{auxverifunari}{\interactiveplot@position}\addtocounter{auxverifunari}{-1}\ifthenelse{\value{auxverifunari}>0\AND\value{auxverifunari}=\arcposition}{}{\StrSubstitute{\interactiveplot@output}{coth(}{ coth(}[\interactiveplot@output]}}}{} \IfSubStr{\interactiveplot@output}{csch(}{\StrPosition{\interactiveplot@output}{csch(}[\interactiveplot@position]\ifthenelse{\interactiveplot@position=0}{\StrSubstitute{\interactiveplot@output}{csch(}{ csch(}[\interactiveplot@output]}{\StrPosition{\interactiveplot@output}{a}[\arcposition]\setcounter{auxverifunari}{\interactiveplot@position}\addtocounter{auxverifunari}{-1}\ifthenelse{\value{auxverifunari}>0\AND\value{auxverifunari}=\arcposition}{}{\StrSubstitute{\interactiveplot@output}{csch(}{ csch(}[\interactiveplot@output]}}}{} \IfSubStr{\interactiveplot@output}{sech(}{\StrPosition{\interactiveplot@output}{sech(}[\interactiveplot@position]\ifthenelse{\interactiveplot@position=0}{\StrSubstitute{\interactiveplot@output}{sech(}{ sech(}[\interactiveplot@output]}{\StrPosition{\interactiveplot@output}{a}[\arcposition]\setcounter{auxverifunari}{\interactiveplot@position}\addtocounter{auxverifunari}{-1}\ifthenelse{\value{auxverifunari}>0\AND\value{auxverifunari}=\arcposition}{}{\StrSubstitute{\interactiveplot@output}{sech(}{ sech(}[\interactiveplot@output]}}}{} \StrSubstitute{\interactiveplot@output}{asinh(}{ asinh(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{acosh(}{ acosh(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{atanh(}{ atanh(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{acoth(}{ acoth(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{asech(}{ asech(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{acsch(}{ acsch(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{exp(}{ exp(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{ln(}{ ln(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{log(}{ log(}[\interactiveplot@output] \expandafter\xdef\csname #2\endcsname{\interactiveplot@output} } %%this macro verify if exist an '[' or ']' in the function and change it for '(' or ')' \def\validateS#1[#2]{ \StrSubstitute{#1}{[}{(}[\interactiveplot@output] \StrSubstitute{\interactiveplot@output}{]}{)}[\interactiveplot@output] \expandafter\xdef\csname #2\endcsname{\interactiveplot@output} } %%this counters are used to validate some things in the code, for example if you define a 2d function, the max number of variables have to be 1, no more, no less, and if you want to define a 3d function the max number of variables have to be 2, no more, no less. \newcount\interactiveplot@maxNumOfVar\interactiveplot@maxNumOfVar=0 \newcount\interactiveplot@actualNumOfVar\interactiveplot@actualNumOfVar=0 \newcount\interactiveplot@actualNumOfF\interactiveplot@actualNumOfF=0 \newcount\interactiveplot@paramCount\interactiveplot@paramCount=0 \newcount\interactiveplot@varCount\interactiveplot@varCount=0 \newcount\interactiveplot@pos\interactiveplot@pos=0 %%here is managed the option "var" in the iplot macro \define@key{iplot}{var}{ \global\advance\interactiveplot@actualNumOfVar by 1 \StrCount{#1}{,}[\interactiveplot@numComma] \ifthenelse{ \the\interactiveplot@actualNumOfVar > \the\interactiveplot@maxNumOfVar}{ \ifthenelse{\the\interactiveplot@maxNumOfVar=1} { \PackageError{\interactiveplot}{Invalid num of variables}{this is a 2D interactive plotter, you have to declare one variable!} } { \PackageError{\interactiveplot}{Invalid num of variables}{this is a 3D interactive plotter, you have to declare two variables!} } } {} \ifthenelse{\interactiveplot@numComma>2\OR\interactiveplot@numComma=1}{ \PackageError{\interactiveplot}{Invalid num of parameters in option var}{it can be only 1 or 3 parameters!} } { \newcount\interactiveplot@index\interactiveplot@index=0 \@for\interactiveplot@varItem:=#1\do{ \ifthenelse{\interactiveplot@index=0} { \ifx\interactiveplot@variablelist\undefined \xdef\interactiveplot@variablelist{\interactiveplot@varItem} \else \xdef\interactiveplot@variablelist{\interactiveplot@variablelist,\interactiveplot@varItem} \fi \IfSubStr{\interactiveplot@nplot}{\interactiveplot@varItem}{}{\PackageError{\interactiveplot}{variable doesnt exist}{VARIABLE doesnt exist in mathematical expression}} \xdef\interactiveplot@var{\interactiveplot@var var variable\the\interactiveplot@render\the\interactiveplot@functions\the\interactiveplot@varCount= new varClass(); } \edef\interactiveplot@varname{\interactiveplot@varItem} \xdef\interactiveplot@var{\interactiveplot@var variable\the\interactiveplot@render\the\interactiveplot@functions\the\interactiveplot@varCount.setName('\interactiveplot@varItem'); } \ifdef{\interactiveplot@varsOfExpression}{\xdef\interactiveplot@varsOfExpression{\interactiveplot@varsOfExpression var \interactiveplot@varItem = variables[\the\interactiveplot@varCount];}}{\xdef\interactiveplot@varsOfExpression{var \interactiveplot@varItem = variables[\the\interactiveplot@varCount];}} } { \ifthenelse{\interactiveplot@index=1} { \xdef\interactiveplot@var{\interactiveplot@var variable\the\interactiveplot@render\the\interactiveplot@functions\the\interactiveplot@varCount.setIni(\interactiveplot@varItem); } } { \ifthenelse{\interactiveplot@index=2} { \xdef\interactiveplot@var{\interactiveplot@var variable\the\interactiveplot@render\the\interactiveplot@functions\the\interactiveplot@varCount.setEnd(\interactiveplot@varItem); } } { } } } \advance\interactiveplot@index by 1 } \xdef\interactiveplot@var{\interactiveplot@var func\the\interactiveplot@render\the\interactiveplot@functions.addVar( variable\the\interactiveplot@render\the\interactiveplot@functions\the\interactiveplot@varCount);} } \advance\interactiveplot@varCount by 1 } %%here is managed the option "frange" in the iplot macro \define@key{iplot}{frange}[functionRange,-1,1]{ \global\advance\interactiveplot@actualNumOfF by 1 \StrCount{#1}{,}[\interactiveplot@numComma] \ifthenelse{ \the\interactiveplot@actualNumOfVar > 2 }{ \PackageError{\interactiveplot}{Invalid num of parameters}{this is a 3D interactive plotter, you have to declare one function range!} } {} \ifthenelse{\interactiveplot@numComma>2\OR\interactiveplot@numComma=1}{ \PackageError{\interactiveplot}{Invalid num of parameters in option var}{it can be only 1 or 3 parameters!} } { \newcount\interactiveplot@index\interactiveplot@index=0 \@for\interactiveplot@varItem:=#1\do{ \ifthenelse{\interactiveplot@index=0} { \xdef\interactiveplot@frange{\interactiveplot@frange var frange\the\interactiveplot@render\the\interactiveplot@functions= new frangeClass(); } \xdef\interactiveplot@frange{\interactiveplot@frange frange\the\interactiveplot@render\the\interactiveplot@functions.setName('\interactiveplot@varItem'); } } { \ifthenelse{\interactiveplot@index=1} { \xdef\interactiveplot@frange{\interactiveplot@frange frange\the\interactiveplot@render\the\interactiveplot@functions.setIni(\interactiveplot@varItem); } } { \ifthenelse{\interactiveplot@index=2} { \xdef\interactiveplot@frange{\interactiveplot@frange frange\the\interactiveplot@render\the\interactiveplot@functions.setEnd(\interactiveplot@varItem); } } { } } } \advance\interactiveplot@index by 1 } \xdef\interactiveplot@frange{\interactiveplot@frange func\the\interactiveplot@render\the\interactiveplot@functions.setFrange( frange\the\interactiveplot@render\the\interactiveplot@functions);} } } %%here is managed the option "param" in the iplot macro \define@key{iplot}{param}{ \StrCount{#1}{,}[\interactiveplot@numComma] \ifthenelse{\interactiveplot@numComma>4\OR\interactiveplot@numComma=0\OR\interactiveplot@numComma=1\OR\interactiveplot@numComma=3}{ \PackageError{\interactiveplot}{Invalid num of parameters in option param}{it can be only 3 or 5 arguments!} } { \xdef\interactiveplot@param{\interactiveplot@param var param\the\interactiveplot@render\the\interactiveplot@functions\the\interactiveplot@paramCount = new paramClass(); } \newcount\interactiveplot@index\interactiveplot@index=0 \@for\interactiveplot@varItem:=#1\do{ \ifthenelse{\interactiveplot@index=0} { \IfSubStr{\interactiveplot@nplot}{\interactiveplot@varItem}{}{\typeout{\interactiveplot@nplot / \interactiveplot@varItem}\PackageError{\interactiveplot}{param doesnt exist}{PARAM doesnt exist in mathematical expression}} \edef\interactiveplot@paramname{\interactiveplot@varItem} \ifx\interactiveplot@parameterlist\undefined \xdef\interactiveplot@parameterlist{~\interactiveplot@varItem~} \else \xdef\interactiveplot@parameterlist{\interactiveplot@parameterlist,~\interactiveplot@varItem~} \fi \xdef\interactiveplot@param{\interactiveplot@param param\the\interactiveplot@render\the\interactiveplot@functions\the\interactiveplot@paramCount.setName('\interactiveplot@varItem'); } \ifdef{\interactiveplot@paramsOfExpression}{\xdef\interactiveplot@paramsOfExpression{\interactiveplot@paramsOfExpression var \interactiveplot@varItem=parameters[\the\interactiveplot@paramCount]; }}{\xdef\interactiveplot@paramsOfExpression{var \interactiveplot@varItem=parameters[\the\interactiveplot@paramCount];}} } { \ifthenelse{\interactiveplot@index=1} { \xdef\interactiveplot@param{\interactiveplot@param param\the\interactiveplot@render\the\interactiveplot@functions\the\interactiveplot@paramCount.setValue(\interactiveplot@varItem); } \ifx\interactiveplot@parameterlistvalues\undefined \xdef\interactiveplot@parameterlistvalues{\interactiveplot@varItem} \else \xdef\interactiveplot@parameterlistvalues{\interactiveplot@parameterlistvalues,\interactiveplot@varItem} \fi \xdef\interactiveplot@valueaux{\interactiveplot@varItem} } { \ifthenelse{\interactiveplot@index=2} { \xdef\interactiveplot@param{\interactiveplot@param param\the\interactiveplot@render\the\interactiveplot@functions\the\interactiveplot@paramCount.setIncrement(\interactiveplot@varItem); } } { \ifthenelse{\interactiveplot@index=3} { \ifthenelse{\interactiveplot@valueaux<\interactiveplot@varItem}{\PackageError{\interactiveplot}{Value is less than minimal value}{use another initial value}}{} \xdef\interactiveplot@param{\interactiveplot@param param\the\interactiveplot@render\the\interactiveplot@functions\the\interactiveplot@paramCount.setIni(\interactiveplot@varItem); } } { \ifthenelse{\interactiveplot@index=4} { \xdef\interactiveplot@param{\interactiveplot@param param\the\interactiveplot@render\the\interactiveplot@functions\the\interactiveplot@paramCount.setEnd(\interactiveplot@varItem); } \ifthenelse{\interactiveplot@valueaux>\interactiveplot@varItem}{\PackageError{\interactiveplot}{Value is greater than maximal value}{use another initial value}}{} } {} } } } } \advance\interactiveplot@index by 1 } \xdef\interactiveplot@param{\interactiveplot@param func\the\interactiveplot@render\the\interactiveplot@functions.addParam( param\the\interactiveplot@render\the\interactiveplot@functions\the\interactiveplot@paramCount); } } \advance\interactiveplot@paramCount by 1 } %%here is managed the option "border" in the iplot macro \define@key{iplot}{border}[1]{ \xdef\border{#1} } %%here is managed the option "color" in the iplot macro \define@key{iplot}{color}[notcolor]{ \edef\interactiveplot@input{#1} \IfStrEqCase{\interactiveplot@input}{ {notcolor}{ \xdef\interactiveplot@color{ func\the\interactiveplot@render\the\interactiveplot@functions.setColor(color.black);} } {black}{ \xdef\interactiveplot@color{ func\the\interactiveplot@render\the\interactiveplot@functions.setColor(color.black);} \ifthenelse{\equal{\interactiveplot@colormanage}{}} {\xdef\interactiveplot@colormanage{black}} {\xdef\interactiveplot@colormanage{\interactiveplot@colormanage,black}} } {white}{ \xdef\interactiveplot@color{ func\the\interactiveplot@render\the\interactiveplot@functions.setColor(color.white);} \ifthenelse{\equal{\interactiveplot@colormanage}{}} {\xdef\interactiveplot@colormanage{white}} {\xdef\interactiveplot@colormanage{\interactiveplot@colormanage,white}} } {red}{ \xdef\interactiveplot@color{func\the\interactiveplot@render\the\interactiveplot@functions.setColor(color.red);} \ifthenelse{\equal{\interactiveplot@colormanage}{}} {\xdef\interactiveplot@colormanage{red}} {\xdef\interactiveplot@colormanage{\interactiveplot@colormanage,red}} } {green}{ \xdef\interactiveplot@color{func\the\interactiveplot@render\the\interactiveplot@functions.setColor(color.green);} \ifthenelse{\equal{\interactiveplot@colormanage}{}} {\xdef\interactiveplot@colormanage{green}} {\xdef\interactiveplot@colormanage{\interactiveplot@colormanage,green}} } {blue}{ \xdef\interactiveplot@color{func\the\interactiveplot@render\the\interactiveplot@functions.setColor(color.blue);} \ifthenelse{\equal{\interactiveplot@colormanage}{}} {\xdef\interactiveplot@colormanage{blue}} {\xdef\interactiveplot@colormanage{\interactiveplot@colormanage,blue}} } {cyan}{ \xdef\interactiveplot@color{func\the\interactiveplot@render\the\interactiveplot@functions.setColor(color.cyan);} \ifthenelse{\equal{\interactiveplot@colormanage}{}} {\xdef\interactiveplot@colormanage{cyan}} {\xdef\interactiveplot@colormanage{\interactiveplot@colormanage,cyan}} } {magenta}{ \xdef\interactiveplot@color{func\the\interactiveplot@render\the\interactiveplot@functions.setColor(color.magenta);} \ifthenelse{\equal{\interactiveplot@colormanage}{}} {\xdef\interactiveplot@colormanage{magenta}} {\xdef\interactiveplot@colormanage{\interactiveplot@colormanage,magenta}} } {yellow}{ \xdef\interactiveplot@color{func\the\interactiveplot@render\the\interactiveplot@functions.setColor(color.yellow);} \ifthenelse{\equal{\interactiveplot@colormanage}{}} {\xdef\interactiveplot@colormanage{yellow}} {\xdef\interactiveplot@colormanage{\interactiveplot@colormanage,yellow}} } {dark-gray}{ \xdef\interactiveplot@color{func\the\interactiveplot@render\the\interactiveplot@functions.setColor(color.dkGray);} \ifthenelse{\equal{\interactiveplot@colormanage}{}} {\xdef\interactiveplot@colormanage{dark-gray}} {\xdef\interactiveplot@colormanage{\interactiveplot@colormanage,dark-gray}} } {gray}{ \xdef\interactiveplot@color{func\the\interactiveplot@render\the\interactiveplot@functions.setColor(color.gray);} \ifthenelse{\equal{\interactiveplot@colormanage}{}} {\xdef\interactiveplot@colormanage{gray}} {\xdef\interactiveplot@colormanage{\interactiveplot@colormanage,gray}} } {light gray}{ \xdef\interactiveplot@color{func\the\interactiveplot@render\the\interactiveplot@functions.setColor(color.ltGray);} \ifthenelse{\equal{\interactiveplot@colormanage}{}} {\xdef\interactiveplot@colormanage{light gray}} {\xdef\interactiveplot@colormanage{\interactiveplot@colormanage,light gray}} } } \ifx\interactiveplot@color\undefined \PackageError{\interactiveplot}{Invalid Color}{try one of these color names: White, Red, Green, Blue, Cyan, Magenta, Yellow, Dark Gray, Gray, Light Gray } \fi } %%here is managed the option "resolution" in the iplot macro \define@key{iplot}{resolution}[default]{ \edef\interactiveplot@input{#1} \IfStrEq{\interactiveplot@input}{default} { \ifthenelse{\the\interactiveplot@maxNumOfVar=1} { \edef\interactiveplot@input{500} \xdef\interactiveplot@resolution{ func\the\interactiveplot@render\the\interactiveplot@functions.setResolution(\interactiveplot@input);} } { \edef\interactiveplot@input{35} \xdef\interactiveplot@resolution{ func\the\interactiveplot@render\the\interactiveplot@functions.setResolution(\interactiveplot@input);} } } { \ifthenelse{\interactiveplot@input>0} { \xdef\interactiveplot@resolution{ func\the\interactiveplot@render\the\interactiveplot@functions.setResolution(\interactiveplot@input);} } { \PackageError{\interactiveplot}{Invalid resolution}{it can be only an positive integer value!} } } } %%here all the options are cleaned \def\interactiveplot@cleanoptions{ \xdef\interactiveplot@var{} \xdef\interactiveplot@frange{} \xdef\interactiveplot@param{} \xdef\border{} \xdef\interactiveplot@color{} \xdef\resolution{} \xdef\width{} \xdef\height{} } \xdef\interactiveplot@functionsmanage{} \xdef\interactiveplot@colormanage{} %%this is the iplot macro definition \newcommand{\iplot}[2][]{ \StrSubstitute{#2}{ }{}[\interactiveplot@nplot] \ifthenelse{\equal{\interactiveplot@functionsmanage}{}} {\xdef\interactiveplot@functionsmanage{\interactiveplot@nplot}} {\xdef\interactiveplot@functionsmanage{\interactiveplot@functionsmanage,\interactiveplot@nplot}} \interactiveplot@cleanoptions \setkeys{iplot}{border,color,resolution,frange,#1} \interactiveplot@verifUnariFunc{\interactiveplot@nplot}[interactiveplot@nplot] \validateS{\interactiveplot@nplot}[interactiveplot@nplot] \StrCount{\interactiveplot@nplot}{(}[\auxopen] \StrCount{\interactiveplot@nplot}{)}[\auxclose] \ifthenelse{\equal{\auxopen}{\auxclose}}{}{ \PackageError{graficainteractiva}{Unbalanced parentheses!}{Maybe you are using an extra parentheses}} \StrLen{\interactiveplot@nplot}[\interactiveplot@auxlen] \ifx\c@ct\undefined \newcounter{ct} \else \setcounter{ct}{0} \fi \ifx\c@len\undefined \newcounter{len} \else \setcounter{len}{0} \fi \setcounter{len}{\interactiveplot@auxlen+1} \ifdef{\stack@slist}{\let\stack@slist\undefined}{} \NewStack{slist}{\relax} \ifdef{\stack@tokens}{\let\stack@tokens\undefined}{} \NewStack{tokens}{\relax} \ifdef{\stack@stack}{\let\stack@stack\undefined}{} \NewStack{stack}{\relax} \ifdef{\stack@stackitp}{\let\stack@stackitp\undefined}{} \NewStack{stackitp}{\relax} \ifdef{\stack@postfix}{\let\stack@postfix\undefined}{} \NewStack{postfix}{\relax} \ifdef{\stack@stackpjs}{\let\stack@stackpjs\undefined}{} \NewStack{stackpjs}{\relax} \xdef\interactiveplot@cadenaux{} %%here begins the process of parse the function using stacks %%first thing to do is interpret the tokens (elements, numbers operators, parenthesis, etc) \forloop{ct}{1}{\value{ct} <\value{len} }% {% \StrChar{\interactiveplot@nplot}{\value{ct}}[\interactiveplot@salida] \interactiveplot@isOperator{\interactiveplot@salida}[result] \ifthenelse{\result=0} { \xdef\interactiveplot@cadenaux{\interactiveplot@cadenaux \interactiveplot@salida} } { \ifthenelse{\result=1} { \ifthenelse{\equal{\interactiveplot@salida}{-}\AND\equal{\interactiveplot@cadenaux}{}} { \ifthenelse{\equal{\Stack{slist}}{\relax}\OR\equal{\Stack{slist}}{(}} { \Push{slist}{-1} \Push{slist}{*} }{ \Push{slist}{+} \Push{slist}{-1} \Push{slist}{*} } } { \ifthenelse{\NOT\equal{\interactiveplot@cadenaux}{}} { \Push{slist}{\interactiveplot@cadenaux} } {} \xdef\interactiveplot@cadenaux{\interactiveplot@salida} \Push{slist}{\interactiveplot@cadenaux} \ifthenelse{\NOT\equal{\Stack{slist}}{\relax}\AND\equal{\interactiveplot@cadenaux}{(}}{ \Push{stack}{\interactiveplot@cadenaux} }{} \ifthenelse{\NOT\equal{\Stack{slist}}{\relax}\AND\equal{\interactiveplot@cadenaux}{)}}{ \Pop{stack} \ifthenelse{\equal{\Stack{stack}}{/}\OR\equal{\Stack{stack}}{sqrt}}{ \Push{slist}{\Stack{stack}} \Pop{stack} }{} }{} \xdef\interactiveplot@cadenaux{} } } { \ifthenelse{\equal{\interactiveplot@salida}{ }}{ \ifthenelse{\NOT\equal{\interactiveplot@cadenaux}{}}{ \Push{slist}{\interactiveplot@cadenaux} }{} \xdef\interactiveplot@cadenaux{} \forloop{ct}{\value{ct}}{\NOT\equal{\interactiveplot@salida}{(}}% {% \StrChar{\interactiveplot@nplot}{\value{ct}}[\interactiveplot@salida] \xdef\interactiveplot@cadenaux{\interactiveplot@cadenaux \interactiveplot@salida} } \ifthenelse{\equal{\interactiveplot@cadenaux}{ sqrt}}{ \Push{stack}{\interactiveplot@cadenaux} \xdef\interactiveplot@cadenaux{\interactiveplot@salida} \Push{stack}{\interactiveplot@cadenaux} \Push{slist}{\interactiveplot@cadenaux} \xdef\interactiveplot@cadenaux{} } { \Push{slist}{\interactiveplot@cadenaux} \xdef\interactiveplot@cadenaux{} } }{} } } } \ifthenelse{\NOT\equal{\interactiveplot@cadenaux}{}}{ \Push{slist}{\interactiveplot@cadenaux} }{} \whiledo{\NOT\equal{\Stack{slist}}{\relax}}% { \Push{tokens}{\Stack{slist}} \interactiveplot@isOperator{\Stack{slist}}[interactiveplot@isoperator] \interactiveplot@isDecimal{\Stack{slist}}[interactiveplot@isdecimal] \interactiveplot@isVariable{\Stack{slist}}[interactiveplot@isvariable] \interactiveplot@isParameter{\Stack{slist}}[interactiveplot@isparameter] \ifthenelse{\equal{\interactiveplot@isoperator}{0}\AND\equal{\interactiveplot@isdecimal}{0}\AND\equal{\interactiveplot@isvariable}{0}\AND\equal{\interactiveplot@isparameter}{0}}{ \PackageError{\interactiveplot}{Param is not previously declared}{Declare the param!} }{} \Pop{slist} \let\interactiveplot@isdecimal\undefined } %%when all the tokens are identified, them begins the process of parse te function, this process start from here %% here the hit of this section of code is convert the function in a postfix expression, the reason of this is to obtain a easy way to operate all the functions (investigate about postfix expression in wikipedia!) \whiledo{\NOT\equal{\Stack{tokens}}{\relax}}{ \interactiveplot@isOperator{\Stack{tokens}}[interactiveplot@isoperator] \ifthenelse{\NOT\equal{\interactiveplot@isoperator}{1}}{ \Push{postfix}{\Stack{tokens}} \Pop{tokens} }{ \interactiveplot@isUnary{\Stack{tokens}}[interactiveplot@isunary] \ifthenelse{\equal{\Stack{stackitp}}{\relax}\OR\equal{\interactiveplot@isunary}{1}}{ \Push{stackitp}{\Stack{tokens}} \Pop{tokens} }{\ifthenelse{\equal{\Stack{tokens}}{)}}{ \whiledo{\NOT\equal{\Stack{stackitp}}{(}\AND\NOT\equal{\Stack{stackitp}}{\relax}}{ \Push{postfix}{\Stack{stackitp}} \Pop{stackitp} } \Pop{stackitp} \Pop{tokens} }{ \interactiveplot@Precedence{\Stack{tokens}}[interactiveplot@precedence] \interactiveplot@PrecedenceInStack{\Stack{stackitp}}[interactiveplot@interactiveplot@precedenceinstack] \ifthenelse{\interactiveplot@precedence>\interactiveplot@interactiveplot@precedenceinstack}{ \Push{stackitp}{\Stack{tokens}} \Pop{tokens} }{ \Push{postfix}{\Stack{stackitp}} \Pop{stackitp} \interactiveplot@Precedence{\Stack{tokens}}[interactiveplot@precedence]\interactiveplot@PrecedenceInStack{\Stack{stackitp}}[interactiveplot@interactiveplot@precedenceinstack] \whiledo{\NOT\equal{\Stack{stackitp}}{\relax}\AND\interactiveplot@precedence<\interactiveplot@interactiveplot@precedenceinstack}{ \Push{postfix}{\Stack{stackitp}} \Pop{stackitp} \interactiveplot@Precedence{\Stack{tokens}}[interactiveplot@precedence] \interactiveplot@PrecedenceInStack{\Stack{stackitp}}[interactiveplot@interactiveplot@precedenceinstack] } \interactiveplot@Precedence{\Stack{tokens}}[interactiveplot@precedence]\interactiveplot@PrecedenceInStack{\Stack{stackitp}}[interactiveplot@interactiveplot@precedenceinstack] \ifthenelse{\NOT\equal{\Stack{stackitp}}{\relax}\AND\equal{\interactiveplot@precedence}{\interactiveplot@interactiveplot@precedenceinstack}}{ \Push{postfix}{\Stack{stackitp}} \Pop{stackitp} \interactiveplot@Precedence{\Stack{tokens}}[interactiveplot@precedence] \interactiveplot@PrecedenceInStack{\Stack{stackitp}}[interactiveplot@interactiveplot@precedenceinstack] }{} \Push{stackitp}{\Stack{tokens}} \Pop{tokens} } } } } } %%and from now the hit is to convert again the postfix expression in a prefix expression, but now the result of all this, is an expression in language JavaScript \ifthenelse{\NOT\equal{\Stack{stackitp}}{\relax}}{ \Push{postfix}{\Stack{stackitp}} \Pop{stackitp} \whiledo{\NOT\equal{\Stack{stackitp}}{\relax}}{ \Push{postfix}{\Stack{stackitp}} \Pop{stackitp} } }{} \whiledo{\NOT\equal{\Stack{postfix}}{\relax}}{ \Push{tokens}{\Stack{postfix}} \Pop{postfix} } \whiledo{\NOT\equal{\Stack{tokens}}{\relax}}{ \interactiveplot@isOperator{\Stack{tokens}}[interactiveplot@isoperator] \ifthenelse{\NOT\equal{\interactiveplot@isoperator}{1}}{ \Push{stackpjs}{\Stack{tokens}} \Pop{tokens} } { \interactiveplot@isUnary{\Stack{tokens}}[interactiveplot@isunary] \ifthenelse{\NOT\equal{\interactiveplot@isunary}{1}}{ \xdef\interactiveplot@opTwo{\Stack{stackpjs}} \Pop{stackpjs} \xdef\interactiveplot@opOne{\Stack{stackpjs}} \Pop{stackpjs} \Special{\Stack{tokens}}[special] \ifthenelse{\NOT\equal{\special}{1}}{ \Push{stackpjs}{(\interactiveplot@opOne\Stack{tokens}\interactiveplot@opTwo)} \Pop{tokens} } { \interactiveplot@FJS{\Stack{tokens}}[fjs] \Push{stackpjs}{\fjs(\interactiveplot@opOne,\interactiveplot@opTwo)} \Pop{tokens} } } { \xdef\interactiveplot@opu{\Stack{stackpjs}} \Pop{stackpjs} \interactiveplot@FJS{\Stack{tokens}}[fjs] \StrChar{\interactiveplot@opu}{1}[\interactiveplot@opuAtZero] \ifthenelse{\equal{\interactiveplot@opuAtZero}{(}}{ \Push{stackpjs}{\fjs\interactiveplot@opu} } { \Push{stackpjs}{\fjs(\interactiveplot@opu)} } \Pop{tokens} } } } %%\Stack{stackpjs} have all the function parsed in JavaScript Language \xdef\interactiveplot@ecuationJS{\Stack{stackpjs}} %%here is defined the javascript class who manage all the attributes of the function this javascript code is inserted in a pdf. \xdef\interactiveplot@functionClass{ function functionClass\the\interactiveplot@render\the\interactiveplot@functions(){ this.variables=new Array(); this.param=new Array(); this.frange=new frangeClass(); this.border=null; this.setBorder=setBorder; function setBorder(border){ this.border=border; } this.color=null; this.setColor=setColor; function setColor(color){ this.color=color; } this.resolution=null; this.setResolution=setResolution; function setResolution(resolution){ this.resolution=resolution; } this.varLen=varLen; function varLen(){ return this.variables.length; } this.paramLen=paramLen; function paramLen(){ return this.param.length; } this.addVar=addVar; function addVar(variable){ this.variables.push(variable); } this.setFrange=setFrange; function setFrange(frange){ this.frange=frange; } this.addParam=addParam; function addParam(param){ this.param.push(param); } this.Expression=Expression; function Expression(variables,parameters){% here is inserted in the javascript code the variables ordered \ifx\interactiveplot@varsOfExpression\undefinded \else \interactiveplot@varsOfExpression \fi \ifx\interactiveplot@paramsOfExpression\undefinded \else \interactiveplot@paramsOfExpression \fi return \interactiveplot@ecuationJS; % and here returns the value of the function evaluated for "variables" and "parameters" values } this.clear=clear; function clear(){ this.variables=new Array(); this.param=new Array(); this.border=null; this.color=null; this.dashed=null; this.varLen=varLen; } } var func\the\interactiveplot@render\the\interactiveplot@functions = new functionClass\the\interactiveplot@render\the\interactiveplot@functions(); %here is defined the variable who store the class, it will look like func00 if in al the pdf exist only one render and one function inside the render! if many renders with many functions it will look like funcNN \interactiveplot@var \interactiveplot@frange \interactiveplot@param \interactiveplot@color \interactiveplot@resolution } \xdef\interactiveplot@varsOfExpression{} \xdef\interactiveplot@paramsOfExpression{} \let\interactiveplot@varsOfExpression\undefined \let\interactiveplot@paramsOfExpression\undefined \xdef\interactiveplot@JScode{\interactiveplot@JScode \interactiveplot@functionClass render\the\interactiveplot@render.functions[\the\interactiveplot@functions] = func\the\interactiveplot@render\the\interactiveplot@functions ; } \advance\interactiveplot@functions by 1 \global\interactiveplot@actualNumOfVar=0 \global\interactiveplot@actualNumOfF=0 \interactiveplot@paramCount=0 \interactiveplot@varCount=0 } %% in this macro are stored some functions that will be used by the principal classes \xdef\interactiveplot@classesJS{ function varClass(){ this.name=null; this.ini=null; this.end=null; this.setName=setName; function setName(name){ this.name=name; } this.setIni=setIni; function setIni(ini){ this.ini=ini; } this.setEnd=setEnd; function setEnd(end){ this.end=end; } this.clear=clear; function clear(){ this.name=null; this.ini=null; this.end=null; } } function frangeClass(){ this.name=null; this.ini=null; this.end=null; this.setName=setName; function setName(name){ this.name=name; } this.setIni=setIni; function setIni(ini){ this.ini=ini; } this.setEnd=setEnd; function setEnd(end){ this.end=end; } this.clear=clear; function clear(){ this.name=null; this.ini=null; this.end=null; } } function paramClass(){ this.name=null; this.ini=null; this.end=null; this.value=null; this.increment=null; this.setName=setName; function setName(name){ this.name=name; } this.setIni=setIni; function setIni(ini){ this.ini=ini; } this.setEnd=setEnd; function setEnd(end){ this.end=end; } this.setValue=setValue; function setValue(value){ this.value=value; } this.setIncrement=setIncrement; function setIncrement(increment){ this.increment=increment; } this.clear=clear; function clear(){ this.name=null; this.ini=null; this.end=null; this.value=null; this.increment=null; } } } \newlength{\interactiveplot@actualTextHeight} \define@key{naturaliplot}{width}[default]{ \ifthenelse{\equal{#1}{default}} { \StrGobbleRight{\the\textwidth}{2}[\gobblerightOut] \xdef\interactiveplot@naturalIplotWidth{\gobblerightOut} } { \xdef\interactiveplot@naturalIplotWidth{#1} } } \define@key{naturaliplot}{height}[default]{ \ifthenelse{\equal{#1}{default}} { \xdef\interactiveplot@factorWidescreen{1.7777777} \setlength{\interactiveplot@actualTextHeight}{\textwidth / \real{\interactiveplot@factorWidescreen}} \StrGobbleRight{\the\interactiveplot@actualTextHeight}{2}[\gobblerightOut] \xdef\interactiveplot@naturalIplotHeight{\gobblerightOut} } { \xdef\interactiveplot@naturalIplotHeight{#1} } } %%here is defined the piloted environment \newenvironment{iplotdd}[1][]{ \global\interactiveplot@maxNumOfVar=1 \ifdef{\interactiveplot@render}{\global\advance\interactiveplot@render by 1}{\newcount\interactiveplot@render\interactiveplot@render=0 } \setkeys{naturaliplot}{width,height,#1} \ifthenelse{\the\interactiveplot@render=0}{ \xdef\interactiveplot@JScode{\interactiveplot@classesJS} } {} \xdef\interactiveplot@JScode{\interactiveplot@JScode var render\the\interactiveplot@render = new Object(); render\the\interactiveplot@render .functions = new Array(); } \catcode`\^=12 \catcode`\~=12 } %%in this space is incerte the pilot macro { \xdef\interactiveplot@JScode{ \interactiveplot@JScode var ubication\the\interactiveplot@render = this.getField("squareUbication\the\interactiveplot@render");%this is very importan, in this variable is stored the pdf ubication of the the actual plot ubication\the\interactiveplot@render.hidden=true; var i; var j; var BasicRangeIniVar=-25; var BasicRangeEndVar=25; var rangini\the\interactiveplot@render; var rangend\the\interactiveplot@render; var frangeini\the\interactiveplot@render; var frangeend\the\interactiveplot@render; var curv= new Array(); %% This cycle checks if any of the functions has a larger limits in the x axis that has already been provided for(i=0;iBasicRangeIniVar){rangini\the\interactiveplot@render = BasicRangeIniVar;} if(rangend\the\interactiveplot@renderrender\the\interactiveplot@render.functions[i].variables[j].ini){rangini\the\interactiveplot@render = render\the\interactiveplot@render.functions[i].variables[j].ini;} if(rangend\the\interactiveplot@renderrender\the\interactiveplot@render.functions[i].frange.ini){frangeini\the\interactiveplot@render = render\the\interactiveplot@render.functions[i].frange.ini;} if(frangeend\the\interactiveplot@render=0;i--){ for( j = 0 ; j render\the\interactiveplot@render.functions[i].param[j].end)){ render\the\interactiveplot@render.functions[i].param[j].value=parseFloat(event.value); curves\the\interactiveplot@render[i].setProps({vertices:curve2d\the\interactiveplot@render(render\the\interactiveplot@render.functions[i],frangeini\the\interactiveplot@render,frangeend\the\interactiveplot@render)}); managed\the\interactiveplot@render[managedcount\the\interactiveplot@render]=[param,render\the\interactiveplot@render.functions[i].param[j].increment,render\the\interactiveplot@render.functions[i].param[j].ini,render\the\interactiveplot@render.functions[i].param[j].end]; managedcount\the\interactiveplot@render++; } else{ app.alert("Value is out of range!. The correct range is between ["+render\the\interactiveplot@render.functions[i].param[j].ini+","+render\the\interactiveplot@render.functions[i].param[j].end+"]"); } } else if(existIn(param,managed\the\interactiveplot@render)){ if(!(event.valuemanaged\the\interactiveplot@render[existInPos(param,managed\the\interactiveplot@render)][3])){ render\the\interactiveplot@render.functions[i].param[j].value=parseFloat(event.value); curves\the\interactiveplot@render[i].setProps({vertices:curve2d\the\interactiveplot@render(render\the\interactiveplot@render.functions[i],frangeini\the\interactiveplot@render,frangeend\the\interactiveplot@render)}); } else{ app.alert("Value is out of range!. The correct range is between ["+managed\the\interactiveplot@render[existInPos(param,managed\the\interactiveplot@render)][2]+","+managed\the\interactiveplot@render[existInPos(param,managed\the\interactiveplot@render)][3]+"]"); } } } } j = 0 ; } } } function existIn(value,array){ for(i=0;i=0;i--){ for( j = 0 ; j render\the\interactiveplot@render.functions[i].param[j].ini){ render\the\interactiveplot@render.functions[i].param[j].value=render\the\interactiveplot@render.functions[i].param[j].value-render\the\interactiveplot@render.functions[i].param[j].increment; curves\the\interactiveplot@render[i].setProps({vertices:curve2d\the\interactiveplot@render(render\the\interactiveplot@render.functions[i],frangeini\the\interactiveplot@render,frangeend\the\interactiveplot@render)}); managed\the\interactiveplot@render[managedcount\the\interactiveplot@render]=[param,render\the\interactiveplot@render.functions[i].param[j].increment,render\the\interactiveplot@render.functions[i].param[j].ini,render\the\interactiveplot@render.functions[i].param[j].end]; managedcount\the\interactiveplot@render++; field.value=render\the\interactiveplot@render.functions[i].param[j].value; } } else if(existIn(param,managed\the\interactiveplot@render)){ if(render\the\interactiveplot@render.functions[i].param[j].value>managed\the\interactiveplot@render[existInPos(param,managed\the\interactiveplot@render)][2]){ render\the\interactiveplot@render.functions[i].param[j].value=render\the\interactiveplot@render.functions[i].param[j].value-managed\the\interactiveplot@render[existInPos(param,managed\the\interactiveplot@render)][1]; curves\the\interactiveplot@render[i].setProps({vertices:curve2d\the\interactiveplot@render(render\the\interactiveplot@render.functions[i],frangeini\the\interactiveplot@render,frangeend\the\interactiveplot@render)}); field.value=render\the\interactiveplot@render.functions[i].param[j].value; } } } } j = 0 ; } managed\the\interactiveplot@render= new Array(); managedcount\the\interactiveplot@render = 0; } function plus\the\interactiveplot@render(param,field){%this function is called she a user click the "plus" button of a parameter var i ; var j ; for(i=render\the\interactiveplot@render.functions.length-1;i>=0;i--){ for( j = 0 ; j ytope){ var modypequena = Math.abs(ytope-y); border=ytope; } else{ var modypequena = Math.abs(ymin-y); border=ymin; } var porcentaje = modypequena/modygrande; var xresult = porcentaje*modxgrande+x; arrayValues.splice(i+1,0,[xresult,border]); } else if(arrayValues[i-1]!=undefined&&!isGraphicable2d(arrayValues[i-1],ytope,ymin)){ xaux = arrayValues[i-1][0]; yaux = arrayValues[i-1][1]; x=arrayValues[i][0]; y=arrayValues[i][1]; var modxgrande = xaux-x; var modygrande = yaux-y; var border; if(yaux>ytope){ var modypequena = Math.abs(ytope-y); border=ytope; } else{ var modypequena = Math.abs(ymin-y); border=ymin; } var porcentaje = modypequena/modygrande; var xresult = porcentaje*modxgrande+x; arrayValues.splice(i-1,0,[xresult,border]); } } else if(!isGraphicable2d(arrayValues[i],ytope,ymin)){ if(arrayValues[i][1]>ytope){ arrayValues[i]=[arrayValues[i][0],ytope]; } else if(arrayValues[i][1]1} { \StrDel[1]{\interactiveplot@parameterlistcpy}{,\interactiveplot@paritem}[\interactiveplot@parlistaux] \xdef\interactiveplot@parameterlistcpy{\interactiveplot@parlistaux} }{} } \StrDel{\interactiveplot@parameterlistcpy}{~}[\interactiveplot@parlistaux] \xdef\interactiveplot@parameterlist{\interactiveplot@parlistaux} \newcount\interactiveplot@ycounter\interactiveplot@ycounter=11 \@for\interactiveplot@paritem:=\interactiveplot@parameterlist\do{ \interactiveplot@plotbuttoncaption{\interactiveplot@paritem\the\interactiveplot@render}{\interactiveplot@paritem} \interactiveplot@plotbutton{\interactiveplot@paritem\the\interactiveplot@render}{plus} \interactiveplot@plotbutton{\interactiveplot@paritem\the\interactiveplot@render}{minus} \interactiveplot@fieldparamvalue{\interactiveplot@paritem\the\interactiveplot@render} \StrCut{\interactiveplot@parameterlistvalues}{,}\interactiveplot@paritemvalue\interactiveplot@parameterlistvalues \xdef\interactiveplot@buttonsmanage{ \interactiveplot@buttonsmanage var button\interactiveplot@paritem\the\interactiveplot@render = this.getField("Button\interactiveplot@paritem\the\interactiveplot@render"); var button\interactiveplot@paritem\the\interactiveplot@render plus = this.getField("Button\interactiveplot@paritem\the\interactiveplot@render plus"); var button\interactiveplot@paritem\the\interactiveplot@render minus = this.getField("Button\interactiveplot@paritem\the\interactiveplot@render minus"); var field\interactiveplot@paritem\the\interactiveplot@render = this.getField("Field\interactiveplot@paritem\the\interactiveplot@render"); var buttontextw=button\interactiveplot@paritem\the\interactiveplot@render.rect[2]-button\interactiveplot@paritem\the\interactiveplot@render.rect[0]; var buttontexth=button\interactiveplot@paritem\the\interactiveplot@render.rect[1]-button\interactiveplot@paritem\the\interactiveplot@render.rect[3]; button\interactiveplot@paritem\the\interactiveplot@render.hidden=false; button\interactiveplot@paritem\the\interactiveplot@render minus.hidden=false; button\interactiveplot@paritem\the\interactiveplot@render plus.hidden=false; field\interactiveplot@paritem\the\interactiveplot@render.rect = [ubication\the\interactiveplot@render.rect[0]-25,ubication\the\interactiveplot@render.rect[1]-\the\interactiveplot@ycounter,ubication\the\interactiveplot@render.rect[0]-2,ubication\the\interactiveplot@render.rect[1]+10-\the\interactiveplot@ycounter]; button\interactiveplot@paritem\the\interactiveplot@render minus.rect=[field\interactiveplot@paritem\the\interactiveplot@render .rect[0]-12,field\interactiveplot@paritem\the\interactiveplot@render.rect[1],field\interactiveplot@paritem\the\interactiveplot@render.rect[0]-2,field\interactiveplot@paritem\the\interactiveplot@render.rect[3]]; button\interactiveplot@paritem\the\interactiveplot@render plus.rect=[button\interactiveplot@paritem\the\interactiveplot@render minus.rect[0]-11,button\interactiveplot@paritem\the\interactiveplot@render minus.rect[1],button\interactiveplot@paritem\the\interactiveplot@render minus.rect[0]-1,button\interactiveplot@paritem\the\interactiveplot@render minus.rect[3]]; button\interactiveplot@paritem\the\interactiveplot@render.rect=[button\interactiveplot@paritem\the\interactiveplot@render plus.rect[0]-buttontextw-1,button\interactiveplot@paritem\the\interactiveplot@render plus.rect[3]+buttontexth,button\interactiveplot@paritem\the\interactiveplot@render plus.rect[0]-1,button\interactiveplot@paritem\the\interactiveplot@render plus.rect[3]]; button\interactiveplot@paritem\the\interactiveplot@render minus.setAction("MouseDown","minus\the\interactiveplot@render('\interactiveplot@paritem',field\interactiveplot@paritem\the\interactiveplot@render);"); button\interactiveplot@paritem\the\interactiveplot@render plus.setAction("MouseDown","plus\the\interactiveplot@render('\interactiveplot@paritem',field\interactiveplot@paritem\the\interactiveplot@render);"); field\interactiveplot@paritem\the\interactiveplot@render.value = \interactiveplot@paritemvalue ; field\interactiveplot@paritem\the\interactiveplot@render.textSize=6; field\interactiveplot@paritem\the\interactiveplot@render.setAction("Keystroke","fieldChange\the\interactiveplot@render('\interactiveplot@paritem',field\interactiveplot@paritem\the\interactiveplot@render);"); button\interactiveplot@paritem\the\interactiveplot@render.delay=true; button\interactiveplot@paritem\the\interactiveplot@render plus.delay=true; button\interactiveplot@paritem\the\interactiveplot@render minus.delay=true; } \advance\interactiveplot@ycounter by 11 } \interactiveplot@ycounter=15 \interactiveplot@pos=0 \@for\functionitem:=\interactiveplot@functionsmanage\do{ \interactiveplot@functionbutton{\the\interactiveplot@render\the\interactiveplot@pos}{\functionitem} \xdef\interactiveplot@buttonsmanage{ \interactiveplot@buttonsmanage var functionButton\the\interactiveplot@render\the\interactiveplot@pos = this.getField("buttonFunctionCaption\the\interactiveplot@render\the\interactiveplot@pos"); var buttontextw\the\interactiveplot@render\the\interactiveplot@pos=functionButton\the\interactiveplot@render\the\interactiveplot@pos.rect[2]-functionButton\the\interactiveplot@render\the\interactiveplot@pos.rect[0]; var buttontexth\the\interactiveplot@render\the\interactiveplot@pos=functionButton\the\interactiveplot@render\the\interactiveplot@pos.rect[1]-functionButton\the\interactiveplot@render\the\interactiveplot@pos.rect[3]; var tabulation=(\interactiveplot@naturalIplotWidth-buttontextw\the\interactiveplot@render\the\interactiveplot@pos)/2; functionButton\the\interactiveplot@render\the\interactiveplot@pos.hidden=false; functionButton\the\interactiveplot@render\the\interactiveplot@pos.fillColor= color.transparent;%%%% functionButton\the\interactiveplot@render\the\interactiveplot@pos.rect=[tabulation+ ubication\the\interactiveplot@render.rect[0],ubication\the\interactiveplot@render.rect[1]-\interactiveplot@naturalIplotHeight-\the\interactiveplot@ycounter,tabulation+ubication\the\interactiveplot@render.rect[0]+buttontextw\the\interactiveplot@render\the\interactiveplot@pos,ubication\the\interactiveplot@render.rect[3]+buttontexth\the\interactiveplot@render\the\interactiveplot@pos*2.1-\interactiveplot@naturalIplotHeight-\the\interactiveplot@ycounter]; var functionColor\the\interactiveplot@render\the\interactiveplot@pos = this.addAnnot({ page: ubication\the\interactiveplot@render.page, type: "Square", borderEffectStyle: "C", borderEffectIntensity: 0, lock: true, readOnly: true, rect:[tabulation+ ubication\the\interactiveplot@render.rect[0]-buttontexth\the\interactiveplot@render\the\interactiveplot@pos*1.5+8, ubication\the\interactiveplot@render.rect[1]-\interactiveplot@naturalIplotHeight-\the\interactiveplot@ycounter+2, tabulation+ubication\the\interactiveplot@render.rect[0]-0.2, ubication\the\interactiveplot@render.rect[3]+buttontexth\the\interactiveplot@render\the\interactiveplot@pos*2.1-\interactiveplot@naturalIplotHeight-\the\interactiveplot@ycounter-2], strokeColor: color.black, fillColor: color.black, width:1.2 }); } \advance\interactiveplot@pos by 1 \advance\interactiveplot@ycounter by 11 } \interactiveplot@pos=0 \@for\interactiveplot@coloritem:=\interactiveplot@colormanage\do{ \xdef\interactiveplot@buttonsmanage{ \interactiveplot@buttonsmanage functionColor\the\interactiveplot@render\the\interactiveplot@pos.setProps({ strokeColor: color.\interactiveplot@coloritem, fillColor: color.\interactiveplot@coloritem }); } \advance\interactiveplot@pos by 1 } \xdef\interactiveplot@colormanage{} \xdef\interactiveplot@functionsmanage{} \global\interactiveplot@pos=0 \global\interactiveplot@functions=0 \global\let\interactiveplot@parameterlist\undefined \interactiveplot@square{\the\interactiveplot@render} } \catcode`\^=7 \catcode`~=13 } %%This is the definition of environment iplotddd \newenvironment{iplotddd}[1][]{ \global\interactiveplot@maxNumOfVar=3 \ifdef{\interactiveplot@render}{\global\advance\interactiveplot@render by 1}{\newcount\interactiveplot@render\interactiveplot@render=0 } \setkeys{naturaliplot}{width,height,#1} \ifthenelse{\the\interactiveplot@render=0}{ \xdef\interactiveplot@JScode{\interactiveplot@classesJS} } {} \xdef\interactiveplot@JScode{\interactiveplot@JScode var render\the\interactiveplot@render = new Object(); render\the\interactiveplot@render .functions = new Array(); } \catcode`\^=12 \catcode`\~=12 } { \xdef\interactiveplot@JScode{ \interactiveplot@JScode var ubication\the\interactiveplot@render = this.getField("squareUbication\the\interactiveplot@render"); ubication\the\interactiveplot@render.hidden=true; var i; var j; var BasicRangeIniVar= new Array(); var BasicRangeEndVar= new Array(); var rangini\the\interactiveplot@render; var rangend\the\interactiveplot@render; var curv= new Array(); for(i=0;iBasicRangeEndVar[j]){ BasicRangeEndVar[j]=render\the\interactiveplot@render.functions[i].variables[j].end; } } } for(i=0;i<2;i++){ if(BasicRangeIniVar[i]==null){ BasicRangeIniVar[i]=-5; } if(BasicRangeEndVar[i]==null){ BasicRangeEndVar[i]=5; } } for(i=0;irangend\the\interactiveplot@render){ rangend\the\interactiveplot@render=render\the\interactiveplot@render.functions[i].frange.end; } } for(i=0;i=0;i--){ for( j = 0 ; j render\the\interactiveplot@render.functions[i].param[j].end)){ render\the\interactiveplot@render.functions[i].param[j].value=parseFloat(event.value); curves\the\interactiveplot@render[i].setProps({vertices:curve2d\the\interactiveplot@render(render\the\interactiveplot@render.functions[i])}); managed\the\interactiveplot@render[managedcount\the\interactiveplot@render]=[param,render\the\interactiveplot@render.functions[i].param[j].increment,render\the\interactiveplot@render.functions[i].param[j].ini,render\the\interactiveplot@render.functions[i].param[j].end]; managedcount\the\interactiveplot@render++; } else{ app.alert("Value is out of range!. The correct range is between ["+render\the\interactiveplot@render.functions[i].param[j].ini+","+render\the\interactiveplot@render.functions[i].param[j].end+"]"); } } else if(existIn(param,managed\the\interactiveplot@render)){ if(!(event.valuemanaged\the\interactiveplot@render[existInPos(param,managed\the\interactiveplot@render)][3])){ render\the\interactiveplot@render.functions[i].param[j].value=parseFloat(event.value); curves\the\interactiveplot@render[i].setProps({vertices:curve2d\the\interactiveplot@render(render\the\interactiveplot@render.functions[i])}); } else{ app.alert("Value is out of range!. The correct range is between ["+managed\the\interactiveplot@render[existInPos(param,managed\the\interactiveplot@render)][2]+","+managed\the\interactiveplot@render[existInPos(param,managed\the\interactiveplot@render)][3]+"]"); } } } } j = 0 ; } } } function existIn(value,array){ for(i=0;i=0;i--){ for( j = 0 ; j render\the\interactiveplot@render.functions[i].param[j].ini){ render\the\interactiveplot@render.functions[i].param[j].value=render\the\interactiveplot@render.functions[i].param[j].value-render\the\interactiveplot@render.functions[i].param[j].increment; var numFunctions=render\the\interactiveplot@render.functions.length; annots_per_function=curve3d\the\interactiveplot@render(render\the\interactiveplot@render.functions[i], render\the\interactiveplot@render.functions[i].param[j].value); for(jj=0;jj