texlive[47566] Master: bezierplot (13apr18)

commits+karl at tug.org commits+karl at tug.org
Wed May 2 19:55:49 CEST 2018


Revision: 47566
          http://tug.org/svn/texlive?view=revision&revision=47566
Author:   karl
Date:     2018-05-02 19:55:49 +0200 (Wed, 02 May 2018)
Log Message:
-----------
bezierplot (13apr18)

Modified Paths:
--------------
    trunk/Master/tlpkg/bin/tlpkg-ctan-check
    trunk/Master/tlpkg/libexec/ctan2tds
    trunk/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/lualatex/bezierplot/
    trunk/Master/texmf-dist/doc/lualatex/bezierplot/README
    trunk/Master/texmf-dist/doc/lualatex/bezierplot/bezierplot-doc.pdf
    trunk/Master/texmf-dist/doc/lualatex/bezierplot/bezierplot-doc.tex
    trunk/Master/texmf-dist/tex/lualatex/bezierplot/
    trunk/Master/texmf-dist/tex/lualatex/bezierplot/bezierplot.lua
    trunk/Master/texmf-dist/tex/lualatex/bezierplot/bezierplot.sty
    trunk/Master/tlpkg/tlpsrc/bezierplot.tlpsrc

Added: trunk/Master/texmf-dist/doc/lualatex/bezierplot/README
===================================================================
--- trunk/Master/texmf-dist/doc/lualatex/bezierplot/README	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/lualatex/bezierplot/README	2018-05-02 17:55:49 UTC (rev 47566)
@@ -0,0 +1,21 @@
+DESCRIPTION:
+bezierplot is a Lua program as well as a (Lua)LaTeX package. 
+Given a smooth function, bezierplot returns a smooth bezier path written
+in TikZ notation (which also matches METAPOST) that approximates the 
+graph of the function. For polynomial functions of degree <= 3 and 
+inverses of them, the approximation is exact. bezierplot finds special 
+points such as extreme points and inflection points and reduces the 
+number of used points.
+
+VERSION:
+1.0 2018-04-12
+
+LICENSE:
+The package and the program are distributed on CTAN under the terms of 
+the LaTeX Project Public License (LPPL) version 1.3c.
+
+Copyright (c) 2018 Linus Romer
+
+Please write to 
+linus dot romer at gmx dot ch
+to submit bug reports, request new features, etc.


Property changes on: trunk/Master/texmf-dist/doc/lualatex/bezierplot/README
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/lualatex/bezierplot/bezierplot-doc.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/lualatex/bezierplot/bezierplot-doc.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/lualatex/bezierplot/bezierplot-doc.pdf	2018-05-02 17:53:59 UTC (rev 47565)
+++ trunk/Master/texmf-dist/doc/lualatex/bezierplot/bezierplot-doc.pdf	2018-05-02 17:55:49 UTC (rev 47566)

Property changes on: trunk/Master/texmf-dist/doc/lualatex/bezierplot/bezierplot-doc.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/lualatex/bezierplot/bezierplot-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/lualatex/bezierplot/bezierplot-doc.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/lualatex/bezierplot/bezierplot-doc.tex	2018-05-02 17:55:49 UTC (rev 47566)
@@ -0,0 +1,181 @@
+% !TEX program = pdfLaTeX --shell-escape
+\documentclass[a4paper]{article}
+\usepackage{tikz,multicol,bezierplot,amsmath,cancel}
+\usepackage[margin=3.5cm,top=1.75cm]{geometry}
+\usepackage{fetamont}
+\title{bezierplot}\author{Linus Romer}
+\DeclareDocumentCommand{\graphcomparison}{ m m }{
+	\begin{center}
+	\begin{tikzpicture}[scale=.4]
+		\draw (0,-5) node[below]{\tiny\texttt{\detokenize{#1}\quad | \detokenize{#2}}};
+		\draw[step=1,thin] (-5,-5) grid (5,5);
+		\draw[thick,->] (-5,0) -- (5.5,0) node[below]{$x$};
+		\draw[thick,->] (0,-5) -- (0,5.5) node[left]{$y$}; 
+		\foreach \x in {-4,-3,-2,-1,1,2,3,4} {\draw (\x,1pt) -- (\x,-1pt) node[below]{\tiny \x};}  
+      		\foreach \y in {-4,-3,-2,-1,1,2,3,4} {\draw (1pt,\y) -- (-1pt,\y) node[left]{\tiny \y};}   
+      		\draw[color=red,domain=-5:5,range=-5:5,samples=1000] plot function{#2};
+		\draw \bezierplot{#1};
+	\end{tikzpicture}
+	\end{center}
+}
+\begin{document}
+\maketitle\noindent
+\section{Introduction}
+\texttt{bezierplot} is a Lua program as well as a (Lua)\LaTeX{} package. This document describes both.
+
+Given a smooth function, \texttt{bezierplot} returns a smooth bezier path written in Ti\emph{k}Z notation (which also matches \MP{}) that approximates the graph of the function. For polynomial functions of degree $\leq 3$ and inverses of them, the approximation is exact. \texttt{bezierplot} finds special graph points such as extreme points and inflection points and reduces the number of used points.
+
+The following example will show a comparison of \textsc{gnuplot} with \verb|bezierplot| for the function $y=\sqrt{x}$ for $0\leq x \leq 5$:
+\begin{center}
+	\begin{tikzpicture}[scale=1.4]
+		\draw (0,0) .. controls (0,0.745) and (1.667,1.491) .. (5,2.236);
+		\draw (0,0) circle(.02) -- (0,0.745) circle( .02);
+		\draw (1.667,1.491) circle(.02) -- (5,2.236) circle( .02);
+		\draw (2.5,.5) node[above]{\verb|bezierplot|};
+		\begin{scope}[shift={(5.2,0)}]
+		\draw[domain=0:5,samples=51] plot function{x**0.5};
+      		\foreach \x in {0,0.1,...,5.05} {\draw  (\x,{\x^0.5}) circle (0.02);}  
+      		\draw (2.5,.5) node[above]{\textsc{gnuplot}};
+      		\end{scope}
+	\end{tikzpicture}
+\end{center}
+\textsc{gnuplot} used 51 samples (no smoothing) and is still quite inexact at the beginning, whereas \verb|bezierplot| uses 4 points only and is exact!
+\section{Installation}
+As \texttt{bezierplot} is written in Lua, the installation depends whether you are using Lua\LaTeX{} or another \LaTeX{} engine.
+\subsection{Installation For Lua\LaTeX{}}
+If you have installed \texttt{bezierplot} by a package manager, the installation is already complete. The manual installation of \texttt{bezierplot} is done in 2 steps:
+\begin{itemize}
+	\item copy the files \texttt{bezierplot.lua} and \texttt{bezierplot.sty} somewhere in your \texttt{texmf} tree (e.g. to \verb|~/texmf/tex/lualatex/bezierplot/bezierplot.sty| and\\
+	\verb|~/texmf/scripts/bezierplot/bezierplot.lua|)
+	\item update the ls-R databases by running \texttt{mktexlsr}
+\end{itemize}
+\subsection{Additional Installation Steps For Other \LaTeX{} Engines}
+You will have to call \texttt{bezierplot} as an external program via the option \texttt{--shell-escape} (\texttt{--write18} for MiK\TeX{}). Therefore, \texttt{bezierplot.lua} has to be copied with the name \texttt{bezierplot} to a place, where your OS can find it. Under Linux this usually means copying to the directory \texttt{/usr/local/bin/}, but for Windows this will probably include more steps (like adding to the \texttt{PATH}). Of course, Lua has to be installed as well. As soon as you can call \texttt{bezierplot} from a command line (e.g. by typing \verb|bezierplot "x^2"|), it should also work with other \LaTeX{} engines. 
+\section{Loading}
+The \texttt{bezierplot} package is loaded with \verb|\usepackage{bezierplot}|. There are no loading options for the package.
+\section{Usage}
+\begin{multicols}{2}
+\noindent A minimal example of Lua\LaTeX{} document could be:
+\begin{verbatim}
+\documentclass{article}
+\usepackage{tikz,bezierplot}
+\begin{document}
+\tikz \draw \bezierplot{x^2};	
+\end{document}
+\end{verbatim}
+\begin{center}
+	\tikz \draw[scale=.7] \bezierplot{x^2};	
+\end{center}
+\end{multicols}
+\noindent
+The command \verb|\bezierplot| has 4 optional arguments in the sense of
+\begin{center}
+	\verb|\bezierplot[XMIN][XMAX][YMIN][YMAX]{FUNCTION}|
+\end{center}
+The defaults are \verb|XMIN| = \verb|YMIN| $= -5$ and  \verb|XMAX| = \verb|YMAX| $= 5$. 
+\begin{center}
+	\begin{tikzpicture}[scale=.7]
+		\draw \bezierplot[-1][2]{x^2};
+		\draw (0,0) node[below]{\verb|\bezierplot[-1][2]{x^2}|};
+		\begin{scope}[shift={(10,0)}]
+		\draw \bezierplot[-1][2][0.5][3]{x^2};
+		\draw (0,0) node[below]{\verb|\bezierplot[-1][2][0.5][3]{x^2}|};
+      		\end{scope}
+	\end{tikzpicture}	
+\end{center}
+You may reverse the graph by making \verb|XMIN| bigger than \verb|XMAX|. E.g.
+\begin{verbatim}
+	\bezierplot[-5][5]{0.5*x+1}
+\end{verbatim}
+returns \verb|(-5,-1.5) -- (5,3.5)|, whereas 
+\begin{verbatim}
+	\bezierplot[5][-5]{0.5*x+1}
+\end{verbatim}
+returns the reversed path \verb|(5,3.5) -- (-5,-1.5)|. This is useful, if you want to cycle a path to a closed area:
+\begin{multicols}{2}
+\begin{verbatim}
+\begin{tikzpicture}
+	\fill[black!30] \bezierplot[-1][1]{2-x^2} 
+	-- \bezierplot[1][-1]{x^3-x} -- cycle;
+	\draw \bezierplot[-1.1][1.1]{2-x^2};
+	\draw \bezierplot[-1.1][1.1]{x^3-x};
+\end{tikzpicture}	
+\end{verbatim}
+\begin{center}
+	\begin{tikzpicture}
+		\fill[black!30] \bezierplot[-1][1]{2-x^2} -- \bezierplot[1][-1]{x^3-x} -- cycle;
+		\draw \bezierplot[-1.1][1.1]{2-x^2};
+		\draw \bezierplot[-1.1][1.1]{x^3-x};
+	\end{tikzpicture}	
+\end{center}
+\end{multicols}
+\subsection{Running Raw \texttt{bezierplot}}
+Of course, you can run \verb|bezierplot.lua| in a terminal without using \LaTeX{}, e.g.
+\begin{verbatim}
+lua bezierplot.lua "3*x^0.8+2"
+\end{verbatim}
+will return
+\begin{verbatim}
+(0,2) .. controls (0.03,2.282) and (0.268,3.244) .. (1,5)
+\end{verbatim}
+You can set the window of the graph as follows:
+\begin{verbatim}
+lua bezierplot.lua "FUNCTION" XMIN XMAX YMIN YMAX
+\end{verbatim}
+e.g.
+\begin{verbatim}
+lua bezierplot.lua "FUNCTION" 0 1 -3 2.5
+\end{verbatim}
+will set $0\leq x\leq 1$ and $-3\leq y\leq 2.5$. You may also omit the $y$--range, hence
+\begin{verbatim}
+lua bezierplot.lua "FUNCTION" 0 1
+\end{verbatim}
+will set $0\leq x\leq 1$ and leave the default $-5\leq y\leq 5$.
+\subsection{Notation Of Functions}
+The function term given to \verb|bezierplot| must contain at most one variable: $x$. E.g. \verb|"2.3*(x-1)^2-3"|. You must not omit \verb|*| operators:
+\begin{center}
+	wrong:\quad $\cancel{\texttt{2x(x+1)}}$ \hfil correct:\quad \texttt{2*x*(x+1)}
+\end{center}
+You have two possibilities to write powers: \verb|"x^2"| and \verb|"x**2"| both mean $x^2$.
+
+\medskip
+
+The following functions and constants are possible:
+\begin{center}
+\begin{tabular}{ll}
+	\verb|abs| & absolute value (remember: your function should still be smooth)\\
+	\verb|acos| & $\cos^{-1}$ inverse function of cosine in radians\\
+	\verb|asin| & $\sin^{-1}$ inverse function of sine in radians\\
+	\verb|atan| & $\tan^{-1}$ inverse function of tangent in radians\\
+	\verb|cbrt| & cube root $\sqrt[3]{\quad}$ that works for negative numbers, too\\
+	\verb|cos| & cosine for angles in radians\\
+	\verb|exp| & the exponential function $e^{(\;)}$\\
+	\verb|e| & the euler constant $e=\mathrm{exp}(1)$\\
+	\verb|log| & the natural logarithm $\mathrm{log}_e(\;)$\\
+	\verb|pi| & Archimedes’ constant $\pi\approx 3.14$\\
+	\verb|sgn| & sign function\\
+	\verb|sin| & sine for angles in radians\\
+	\verb|sqrt| & square root $\sqrt{\quad}$\\
+	\verb|tan| & tangent for angles in radians\\
+\end{tabular}
+\end{center}
+\section{Examples of \texttt{bezierplot} in Comparison with \textsc{gnuplot}}
+The following graphs are drawn with \texttt{bezierplot} (black) and \textsc{gnuplot} (red). \textsc{gnuplot} used 1000 samples per example. The functions are given below the pictures (left: bezierplot, right: \textsc{gnuplot}).
+\begin{multicols}{3}
+\graphcomparison{0.32*x-0.7}{0.32*x-0.7}
+\graphcomparison{-x^2+4}{-x**2+4}
+\graphcomparison{(x+1)*x*(x-1)}{(x+1)*x*(x-1)}
+\graphcomparison{x^0.5}{x**0.5}
+%\graphcomparison{x^(1/3)}{x**(1/3.)}
+\graphcomparison{cbrt(x)}{sgn(x)*abs(x)**(1/3.)}
+\graphcomparison{x^3*(x-1)}{x**3*(x-1)}
+\graphcomparison{2*cos(3*x+4)+3}{2*cos(3*x+4)+3}
+\graphcomparison{tan(x)}{tan(x)}
+\graphcomparison{x+0.5*sin(x)}{x+0.5*sin(x)}
+%\graphcomparison{1/(x-2)+1}{1/(x-2)+1}
+\graphcomparison{2*x^2/(3*x-3)}{2*x**2/(3*x-3)}
+\graphcomparison{4-exp(x)}{4-exp(x)}
+\graphcomparison{log(x+4)}{log(x+4)}
+\end{multicols}
+
+\end{document}


Property changes on: trunk/Master/texmf-dist/doc/lualatex/bezierplot/bezierplot-doc.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/lualatex/bezierplot/bezierplot.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/bezierplot/bezierplot.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/lualatex/bezierplot/bezierplot.lua	2018-05-02 17:55:49 UTC (rev 47566)
@@ -0,0 +1,698 @@
+#!/usr/bin/env lua
+-- Linus Romer, published 2018 under LPPL Version 1.3c
+-- version 1.0 2018-04-12
+abs = math.abs
+acos = math.acos
+asin = math.asin
+atan = math.atan
+cos = math.cos
+exp = math.exp
+e = math.exp(1)
+log = math.log
+pi = math.pi
+sin = math.sin
+sqrt = math.sqrt
+tan = math.tan
+
+-- cube root defined for all real numbers x
+function cbrt(x)
+	if x < 0 then
+		return -(-x)^(1/3)
+	else
+		return x^(1/3)
+	end
+end
+
+function sgn(x)
+	if x<0 then
+		return -1
+	elseif x>0 then
+		return 1
+	else
+		return 0
+	end
+end
+
+function round(num, decimals)
+	local result = tonumber(string.format("%." .. (decimals or 0) .. "f", num))
+	if abs(result) == 0 then
+		return 0
+	else
+		return result
+	end
+end
+
+-- 5-stencil method
+-- return from a graph from f in the form {{x,y},...}
+-- the derivatives in form {{x,y,dy/dx,ddy/ddx},...}
+function diffgraph(func,graph,h)
+	local dgraph = {}	
+	local yh = func(graph[1][1]-h)
+	local yhh = func(graph[1][1]-2*h)
+	if yhh > -math.huge and yhh < math.huge  -- if defined at all
+	and yh > -math.huge and yh < math.huge then
+		dgraph[1] = {graph[1][1],graph[1][2],
+		(yhh-8*yh+8*graph[2][2]-graph[3][2])/(12*h),
+		(-yhh+16*yh-30*graph[1][2]+16*graph[2][2]-graph[3][2])
+		/(12*h^2)}
+		dgraph[2] = {graph[2][1],graph[2][2],
+		(yh-8*graph[1][2]+8*graph[3][2]-graph[4][2])/(12*h),
+		(-yh+16*graph[1][2]-30*graph[2][2]+16*graph[3][2]-graph[4][2])
+		/(12*h^2)}
+	else -- take neighbour values
+		dgraph[1] = {graph[1][1],graph[1][2],
+		(graph[1][2]-8*graph[2][2]+8*graph[4][2]-graph[5][2])/(12*h),
+		(-graph[1][2]+16*graph[2][2]-30*graph[3][2]
+		+16*graph[4][2]-graph[5][2])/(12*h^2)}
+		dgraph[2] = {graph[2][1],graph[2][2],
+		(graph[1][2]-8*graph[2][2]+8*graph[4][2]-graph[5][2])/(12*h),
+		(-graph[1][2]+16*graph[2][2]-30*graph[3][2]
+		+16*graph[4][2]-graph[5][2])/(12*h^2)}
+	end
+	local l = #graph
+	for i = 3, l-2 do 
+		table.insert(dgraph,{graph[i][1],graph[i][2],
+		(graph[i-2][2]-8*graph[i-1][2]+8*graph[i+1][2]-graph[i+2][2])
+		/(12*h),
+		(-graph[i-2][2]+16*graph[i-1][2]-30*graph[i][2]
+		+16*graph[i+1][2]-graph[i+2][2])
+		/(12*h^2)})
+	end
+	yh = func(graph[l][1]+h)
+	yhh = func(graph[l][1]+2*h)
+	if yhh > -math.huge and yhh < math.huge  -- if defined at all
+	and yh > -math.huge and yh < math.huge then
+		dgraph[l-1] = {graph[l-1][1],graph[l-1][2],
+		(graph[l-3][2]-8*graph[l-2][2]+8*graph[l][2]-yh)/(12*h),
+		(-graph[l-3][2]+16*graph[l-2][2]-30*graph[l-1][2]
+		+16*graph[l][2]-yh)/(12*h^2)}
+		dgraph[l] = {graph[l][1],graph[l][2],
+		(graph[l-2][2]-8*graph[l-1][2]+8*yh-yhh)/(12*h),
+		(-graph[l-2][2]+16*graph[l-1][2]-30*graph[l][2]
+		+16*yh-yhh)/(12*h^2)}
+	else	
+		-- take neighbour values
+		dgraph[l] = {graph[l][1],graph[l][2],
+		(graph[l-4][2]-8*graph[l-3][2]+8*graph[l-1][2]-graph[l][2])
+		/(12*h),
+		(-graph[l-4][2]+16*graph[l-3][2]-30*graph[l-2][2]
+		+16*graph[l-1][2]-graph[l][2])/(12*h^2)}
+		dgraph[l-1] = {graph[l-1][1],graph[l-2][2],
+		(graph[l-4][2]-8*graph[l-3][2]+8*graph[l-1][2]-graph[l][2])
+		/(12*h),
+		(-graph[l-4][2]+16*graph[l-3][2]-30*graph[l-2][2]
+		+16*graph[l-1][2]-graph[l][2])/(12*h^2)}
+	end
+	-- add information about being extremum / inflection point (true/false)
+	for i = 1, l do 
+		dgraph[i][5] = false -- dy/dx == 0 ? default, may change later
+		dgraph[i][6] = false -- ddy/ddx == 0 ? default, may change later
+	end
+	for i = 1, l-1 do 
+		-- if no gap is inbetween
+		if not (dgraph[i+1][1] - dgraph[i][1] > 1.5*h) then
+			-- check for dy/dx == 0 
+			-- if not already determined as near dy/dx=0
+			if not dgraph[i][5] then 
+				if dgraph[i][3] == 0 then
+					dgraph[i][5] = true
+				elseif abs(dgraph[i][3]*dgraph[i+1][3]) 
+				~= dgraph[i][3]*dgraph[i+1][3] then -- this must be near
+					if abs(dgraph[i][4]) <= abs(dgraph[i+1][4]) then
+						dgraph[i][5] = true
+					else
+						dgraph[i+1][5] = true
+					end
+				end
+			end
+			-- check for ddy/ddx == 0 
+			-- if not already determined as near ddy/ddx=0
+			if not dgraph[i][6] then 
+				if abs(dgraph[i][4]*dgraph[i+1][4]) 
+				~= dgraph[i][4]*dgraph[i+1][4] then -- this must be near
+					if abs(dgraph[i][4]) <= abs(dgraph[i+1][4]) then
+						dgraph[i][6] = true
+					else
+						dgraph[i+1][6] = true
+					end
+				end
+			end
+		end
+	end
+	return dgraph
+end
+
+-- checks for 100 x, if the function given by funcstring
+-- fits the graph g (up to maxerror) after filling in
+-- the parameters a, b, c, d
+-- if the graph is inverted, then isinverse has to be set true
+function do_parameters_fit(a,b,c,d,funcstring,funcgraph,maxerror,isinverse)
+	local funcx = string.gsub(funcstring, "a", a)
+	local funcx = string.gsub(funcx, "b", b)
+	local funcx = string.gsub(funcx, "c", c)
+	local funcx = string.gsub(funcx, "d", d)
+	local func = assert(load("local x = ...; return "..funcx))
+	for i = 1, #funcgraph, math.max(1,math.floor(0.01*#funcgraph)) do 
+		if isinverse then
+			if abs(func(funcgraph[i][2])-funcgraph[i][1]) 
+			> maxerror then
+				return false
+			end
+		else
+			if abs(func(funcgraph[i][1])-funcgraph[i][2]) 
+			> maxerror then
+				return false
+			end
+		end
+	end
+	return true
+end
+
+-- f(x)=a*x^3+b*x+c
+function parameters_cubic(xp,yp,xq,yq,xr,yr,xs,ys)
+	local a = (((xp^2 * xq) * yr) - ((xp^2 * xq) * ys) 
+	- ((xp^2 * xr) * yq) + ((xp^2 * xr) * ys) + ((xp^2 * xs) * yq)
+	- ((xp^2 * xs) * yr) - ((xp * xq^2) * yr) + ((xp * xq^2) * ys) 
+	+ ((xp * xr^2) * yq) - ((xp * xr^2) * ys) - ((xp * xs^2) * yq) 
+	+ ((xp * xs^2) * yr) + ((xq^2 * xr) * yp) - ((xq^2 * xr) * ys) 
+	- ((xq^2 * xs) * yp) + ((xq^2 * xs) * yr) - ((xq * xr^2) * yp) 
+	+ ((xq * xr^2) * ys) + ((xq * xs^2) * yp) - ((xq * xs^2) * yr) 
+	+ ((xr^2 * xs) * yp) - ((xr^2 * xs) * yq) - ((xr * xs^2) * yp) 
+	+ ((xr * xs^2) * yq)) / 
+	(((xp^3 * xq^2) * xr) - ((xp^3 * xq^2) * xs) 
+	- ((xp^3 * xq) * xr^2) + ((xp^3 * xq) * xs^2) 
+	+ ((xp^3 * xr^2) * xs) - ((xp^3 * xr) * xs^2) 
+	- ((xp^2 * xq^3) * xr) + ((xp^2 * xq^3) * xs) 
+	+ ((xp^2 * xq) * xr^3) - ((xp^2 * xq) * xs^3) 
+	- ((xp^2 * xr^3) * xs) + ((xp^2 * xr) * xs^3) 
+	+ ((xp * xq^3) * xr^2) - ((xp * xq^3) * xs^2) 
+	- ((xp * xq^2) * xr^3) + ((xp * xq^2) * xs^3) 
+	+ ((xp * xr^3) * xs^2) - ((xp * xr^2) * xs^3) 
+	- ((xq^3 * xr^2) * xs) + ((xq^3 * xr) * xs^2) 
+	+ ((xq^2 * xr^3) * xs) - ((xq^2 * xr) * xs^3) 
+	- ((xq * xr^3) * xs^2) + ((xq * xr^2) * xs^3))
+	local b = ((((-xp^3) * xq) * yr) + ((xp^3 * xq) * ys) 
+	+ ((xp^3 * xr) * yq) - ((xp^3 * xr) * ys) - ((xp^3 * xs) * yq) 
+	+ ((xp^3 * xs) * yr) + ((xp * xq^3) * yr) - ((xp * xq^3) * ys) 
+	- ((xp * xr^3) * yq) + ((xp * xr^3) * ys) + ((xp * xs^3) * yq) 
+	- ((xp * xs^3) * yr) - ((xq^3 * xr) * yp) + ((xq^3 * xr) * ys) 
+	+ ((xq^3 * xs) * yp) - ((xq^3 * xs) * yr) + ((xq * xr^3) * yp) 
+	- ((xq * xr^3) * ys) - ((xq * xs^3) * yp) + ((xq * xs^3) * yr) 
+	- ((xr^3 * xs) * yp) + ((xr^3 * xs) * yq) + ((xr * xs^3) * yp) 
+	- ((xr * xs^3) * yq)) / 
+	(((xp^3 * xq^2) * xr) - ((xp^3 * xq^2) * xs) 
+	- ((xp^3 * xq) * xr^2) + ((xp^3 * xq) * xs^2) 
+	+ ((xp^3 * xr^2) * xs) - ((xp^3 * xr) * xs^2) 
+	- ((xp^2 * xq^3) * xr) + ((xp^2 * xq^3) * xs) 
+	+ ((xp^2 * xq) * xr^3) - ((xp^2 * xq) * xs^3) 
+	- ((xp^2 * xr^3) * xs) + ((xp^2 * xr) * xs^3) 
+	+ ((xp * xq^3) * xr^2) - ((xp * xq^3) * xs^2) 
+	- ((xp * xq^2) * xr^3) + ((xp * xq^2) * xs^3) 
+	+ ((xp * xr^3) * xs^2) - ((xp * xr^2) * xs^3) 
+	- ((xq^3 * xr^2) * xs) + ((xq^3 * xr) * xs^2) 
+	+ ((xq^2 * xr^3) * xs) - ((xq^2 * xr) * xs^3) 
+	- ((xq * xr^3) * xs^2) + ((xq * xr^2) * xs^3))
+	local c = (((xp^3 * xq^2) * yr) - ((xp^3 * xq^2) * ys) 
+	- ((xp^3 * xr^2) * yq) + ((xp^3 * xr^2) * ys) 
+	+ ((xp^3 * xs^2) * yq) - ((xp^3 * xs^2) * yr) 
+	- ((xp^2 * xq^3) * yr) + ((xp^2 * xq^3) * ys) 
+	+ ((xp^2 * xr^3) * yq) - ((xp^2 * xr^3) * ys) 
+	- ((xp^2 * xs^3) * yq) + ((xp^2 * xs^3) * yr) 
+	+ ((xq^3 * xr^2) * yp) - ((xq^3 * xr^2) * ys) 
+	- ((xq^3 * xs^2) * yp) + ((xq^3 * xs^2) * yr) 
+	- ((xq^2 * xr^3) * yp) + ((xq^2 * xr^3) * ys) 
+	+ ((xq^2 * xs^3) * yp) - ((xq^2 * xs^3) * yr) 
+	+ ((xr^3 * xs^2) * yp) - ((xr^3 * xs^2) * yq) 
+	- ((xr^2 * xs^3) * yp) + ((xr^2 * xs^3) * yq)) / 
+	(((xp^3 * xq^2) * xr) - ((xp^3 * xq^2) * xs) 
+	- ((xp^3 * xq) * xr^2) + ((xp^3 * xq) * xs^2) 
+	+ ((xp^3 * xr^2) * xs) - ((xp^3 * xr) * xs^2) 
+	- ((xp^2 * xq^3) * xr) + ((xp^2 * xq^3) * xs) 
+	+ ((xp^2 * xq) * xr^3) - ((xp^2 * xq) * xs^3) 
+	- ((xp^2 * xr^3) * xs) + ((xp^2 * xr) * xs^3) 
+	+ ((xp * xq^3) * xr^2) - ((xp * xq^3) * xs^2) 
+	- ((xp * xq^2) * xr^3) + ((xp * xq^2) * xs^3) 
+	+ ((xp * xr^3) * xs^2) - ((xp * xr^2) * xs^3) 
+	- ((xq^3 * xr^2) * xs) + ((xq^3 * xr) * xs^2) 
+	+ ((xq^2 * xr^3) * xs) - ((xq^2 * xr) * xs^3) 
+	- ((xq * xr^3) * xs^2) + ((xq * xr^2) * xs^3))
+	local d = ((((xp^(3) * xq^(2)) * xr) * ys) 
+	- (((xp^(3) * xq^(2)) * xs) * yr) - (((xp^(3) * xq) * xr^(2)) * ys) 
+	+ (((xp^(3) * xq) * xs^(2)) * yr) + (((xp^(3) * xr^(2)) * xs) * yq) 
+	- (((xp^(3) * xr) * xs^(2)) * yq) - (((xp^(2) * xq^(3)) * xr) * ys) 
+	+ (((xp^(2) * xq^(3)) * xs) * yr) + (((xp^(2) * xq) * xr^(3)) * ys) 
+	- (((xp^(2) * xq) * xs^(3)) * yr) - (((xp^(2) * xr^(3)) * xs) * yq) 
+	+ (((xp^(2) * xr) * xs^(3)) * yq) + (((xp * xq^(3)) * xr^(2)) * ys) 
+	- (((xp * xq^(3)) * xs^(2)) * yr) - (((xp * xq^(2)) * xr^(3)) * ys) 
+	+ (((xp * xq^(2)) * xs^(3)) * yr) + (((xp * xr^(3)) * xs^(2)) * yq) 
+	- (((xp * xr^(2)) * xs^(3)) * yq) - (((xq^(3) * xr^(2)) * xs) * yp) 
+	+ (((xq^(3) * xr) * xs^(2)) * yp) + (((xq^(2) * xr^(3)) * xs) * yp) 
+	- (((xq^(2) * xr) * xs^(3)) * yp) - (((xq * xr^(3)) * xs^(2)) * yp) 
+	+ (((xq * xr^(2)) * xs^(3)) * yp)) / 
+	(((xp^(3) * xq^(2)) * xr) - 
+	((xp^(3) * xq^(2)) * xs) - ((xp^(3) * xq) * xr^(2)) 
+	+ ((xp^(3) * xq) * xs^(2)) + ((xp^(3) * xr^(2)) * xs) 
+	- ((xp^(3) * xr) * xs^(2)) - ((xp^(2) * xq^(3)) * xr) 
+	+ ((xp^(2) * xq^(3)) * xs) + ((xp^(2) * xq) * xr^(3)) 
+	- ((xp^(2) * xq) * xs^(3)) - ((xp^(2) * xr^(3)) * xs) 
+	+ ((xp^(2) * xr) * xs^(3)) + ((xp * xq^(3)) * xr^(2)) 
+	- ((xp * xq^(3)) * xs^(2)) - ((xp * xq^(2)) * xr^(3)) 
+	+ ((xp * xq^(2)) * xs^(3)) + ((xp * xr^(3)) * xs^(2)) 
+	- ((xp * xr^(2)) * xs^(3)) - ((xq^(3) * xr^(2)) * xs) 
+	+ ((xq^(3) * xr) * xs^(2)) + ((xq^(2) * xr^(3)) * xs) 
+	- ((xq^(2) * xr) * xs^(3)) - ((xq * xr^(3)) * xs^(2)) 
+	+ ((xq * xr^(2)) * xs^(3)))
+	return a, b, c, d
+end
+
+-- f(x)=a*x+b
+function parameters_affine(xp,yp,xq,yq)
+	local a = (yp - yq) / (xp - xq)
+	local b = ((xp * yq) - (xq * yp)) / (xp - xq)
+	return a, b
+end
+
+-- returns true iff the function is of type f(x)=a*x^3+b*x^2+c*x+d
+-- a, b, c, d being real numbers
+function is_cubic(graph,maxerror)
+	local l = #graph
+	local a, b, c, d = parameters_cubic(graph[1][1],graph[1][2],
+	graph[math.floor(l/3)][1],graph[math.floor(l/3)][2],
+	graph[math.floor(2*l/3)][1],graph[math.floor(2*l/3)][2],
+	graph[l][1],graph[l][2])
+	return do_parameters_fit(a,b,c,d,"a*x^3+b*x^2+c*x+d",graph,
+	maxerror,false)
+end
+
+-- returns true iff the function is of type f(x)=a*x^3+b*x^2+c*x+d
+-- a, b, c, d being real numbers
+-- this takes several graph parts
+-- the idea is to have a possibility to avoid tan(x)
+function are_cubic(graphs,maxerror)
+	if is_cubic(graphs[1],maxerror) then
+		if #graphs < 2 then
+			return true
+		else -- check for the next part
+			local a, b, c, d = parameters_cubic(graphs[1][1][1],
+			graphs[1][1][2],graphs[1][math.floor(l/3)][1],
+			graphs[1][math.floor(l/3)][2],
+			graphs[1][math.floor(2*l/3)][1],
+			graphs[1][math.floor(2*l/3)][2],
+			graphs[1][l][1],graphs[1][l][2])
+			return do_parameters_fit(a,b,c,d,"a*x^3+b*x^2+c*x+d",
+			graphs[2],maxerror,false)
+		end
+	else
+		return false
+	end
+end
+
+-- returns true iff the inverse function is of type 
+-- f(x)=a*x^3+b*x^2+c*x+d
+-- a, b, c, d being real numbers
+function is_cuberoot(graph,maxerror)
+	local l = #graph
+	local a, b, c, d = parameters_cubic(graph[1][2],graph[1][1],
+	graph[math.floor(l/3)][2],graph[math.floor(l/3)][1],
+	graph[math.floor(2*l/3)][2],graph[math.floor(2*l/3)][1],
+	graph[l][2],graph[l][1])
+	return do_parameters_fit(a,b,c,d,"a*x^3+b*x^2+c*x+d",graph,
+	maxerror,true)
+end
+
+-- returns true iff the function is of type f(x)=a*x^3+b*x^2+c*x+d
+-- a, b, c, d being real numbers
+-- this takes several graph parts
+-- the idea is to have a possibility to avoid tan(x)
+function are_cuberoot(graphs,maxerror)
+	if is_cuberoot(graphs[1],maxerror) then
+		if #graphs < 2 then
+			return true
+		else -- check for the next part
+			local a, b, c, d = parameters_cubic(graphs[1][1][2],
+			graphs[1][1][1],graphs[1][math.floor(l/3)][2],
+			graphs[1][math.floor(l/3)][1],
+			graphs[1][math.floor(2*l/3)][2],
+			graphs[1][math.floor(2*l/3)][1],
+			graphs[1][l][2],graphs[1][l][1])
+			return do_parameters_fit(a,b,c,d,"a*x^3+b*x^2+c*x+d",
+			graphs[2],maxerror,true)
+		end
+	else
+		return false
+	end
+end
+
+-- returns true iff function is of type f(x)=a*x+b
+-- a, b being real numbers
+function is_affine(graph,maxerror)
+	l = #graph
+	local a, b = parameters_affine(graph[1][1],graph[1][2],
+	graph[l][1],graph[l][2])
+	return do_parameters_fit(a,b,0,0,"a*x+b",graph,maxerror,false)
+end
+
+-- what is the sum of the squared error
+-- when comparing the bezier path
+-- p.. control q and r .. s
+-- with the graph g from index starti to endi
+-- (looking at the points at roughly t=.33 and t=.67)
+function squareerror(f,g,starti,endi,qx,qy,rx,ry)
+	local result = 0
+	for t = .33, .7, .34 do
+		x = (1-t)^3*g[starti][1]+3*t*(1-t)^2*qx+3*t^2*(1-t)*rx+t^3*g[endi][1]
+		y = (1-t)^3*g[starti][2]+3*t*(1-t)^2*qy+3*t^2*(1-t)*ry+t^3*g[endi][2]
+		result = result + (y-f(x))^2
+	end
+	return result
+end
+
+function pointstobezier(qx,qy,rx,ry,sx,sy,rndx,rndy)
+	return " .. controls (" .. round(qx,rndx) .. "," 
+	.. round(qy,rndy) ..") and ("
+	.. round(rx,rndx) .. "," 
+	.. round(ry,rndy) .. ") .. (" 
+	.. round(sx,rndx) .. "," 
+	.. round(sy,rndy)..")"
+end
+
+-- take end points of a graph g of the function f
+-- (from indices starti to endi)
+-- without extrema or inflection points inbetween 
+-- and try to approximate it with a cubic bezier curve
+-- (round to rndx and rndy when printing)
+function graphtobezierapprox(f,g,starti,endi,rndx,rndy,maxerror)
+	local px = g[starti][1]
+	local py = g[starti][2]
+	local dp = g[starti][3]
+	local sx = g[endi][1]
+	local sy = g[endi][2]
+	local ds = g[endi][3]
+	-- we compute the corner point c, where the controls would meet
+	local cx = ((dp * px) - (ds * sx) - py + sy) / (dp - ds)
+	local cy = (dp * ((ds * px) - (ds * sx) - py + sy) / (dp - ds)) + py
+	-- now we slide q between p and c & r between s and c
+	-- and search for the best qx and best rx
+	local qx = px+.05*(cx-px)
+	local qy = py+.05*(cy-py)
+	local rx = sx+.05*(cx-sx)
+	local ry = sy+.05*(cy-sy)
+	local err = squareerror(f,g,starti,endi,qx,qy,rx,ry)
+	for i = 2, 19 do
+		for j = 2, 19 do
+			xa = px+i*.05*(cx-px)
+			ya = py+i*.05*(cy-py)
+			xb = sx+j*.05*(cx-sx)
+			yb = sy+j*.05*(cy-sy)
+			-- now check, if xa and xb fit better
+			-- at roughly t=0.33 and t=0.66 for f(x)
+			-- than the last qx and rx did
+			-- (sum of squares must be smaller)
+			if squareerror(f,g,starti,endi,xa,ya,xb,yb) < err then
+				qx = xa
+				qy = ya
+				rx = xb
+				ry = yb
+				err = squareerror(f,g,starti,endi,qx,qy,rx,ry)
+			end
+		end
+	end
+	-- check if it is close enough: (recycling err, xa, ya)
+	err = 0
+	for t = .1, .9, .1 do
+		xa = (1-t)^3*g[starti][1]+3*t*(1-t)^2*qx+3*t^2*(1-t)*rx+t^3*g[endi][1]
+		ya = (1-t)^3*g[starti][2]+3*t*(1-t)^2*qy+3*t^2*(1-t)*ry+t^3*g[endi][2]
+		if abs(ya-f(xa)) > err then
+			err = abs(ya-f(xa))
+		end
+	end
+	if err <= maxerror then
+		return pointstobezier(qx,qy,rx,ry,sx,sy,rndx,rndy)
+	else
+		-- search for an intermediate point where the graph has the same
+		-- slope as the line from the start point to the end point:
+		local interindex = math.floor(.5*starti+.5*endi) -- will change
+		for i = starti + 1, endi - 1 do
+			if abs(g[i][3]-(g[endi][2]-g[starti][2])
+			/(g[endi][1]-g[starti][1])) 
+			< abs(g[interindex][3]-(g[endi][2]-g[starti][2])
+			/(g[endi][1]-g[starti][1])) then
+				interindex = i
+			end
+		end
+		return graphtobezierapprox(f,g,starti,interindex,rndx,rndy,maxerror)
+		.. graphtobezierapprox(f,g,interindex,endi,rndx,rndy,maxerror)
+	end
+end
+
+-- like above but exact for quadratic and cubic (if not inverse)
+-- resp. exact for squareroot and cuberoot (if inverse)
+function graphtobezier(g,starti,endi,rndx,rndy,isinverse)
+	local px = g[starti][1]
+	local py = g[starti][2]
+	local dp = g[starti][3]
+	local sx = g[endi][1]
+	local sy = g[endi][2]
+	local ds = g[endi][3]
+	local qx = px+(sx-px)/3
+	local rx = px+2*(sx-px)/3
+	local qy = py+(qx-px)*dp
+	local ry = sy+(rx-sx)*ds
+	if isinverse then
+		return pointstobezier(qy,qx,ry,rx,sy,sx,rndy,rndx)
+	else
+		return pointstobezier(qx,qy,rx,ry,sx,sy,rndx,rndy)
+	end
+end
+
+-- reverses a path p e.g. when p = "(0,1) -- (2,3)"
+-- it returns "(2,3) -- (0,1)"
+-- or when p = "(0,1) .. controls (2,3) and (4,5) .. (6,7)"
+-- it returns "(6,7) .. controls (4,5) and (2,3) .. (0,1)"
+function reversepath(p)
+	local r = "" -- will become the reverse path
+	local temppoint  ="" -- will store temporal points like "(0,1)"
+	local tempbetween = "" -- will store things like " .. controls "
+	for i = 1, #p do
+		local c = string.sub(p,i,i)
+		if c == "(" then
+			if tempbetween == " .. " then
+				r = " .. controls " .. r
+			elseif tempbetween == " .. controls " then
+				r = " .. " .. r
+			else
+				r = tempbetween .. r
+			end
+			tempbetween = ""
+			temppoint = "("
+		elseif c == ")" then
+			r = temppoint .. ")" .. r
+			temppoint = ""
+		else
+			if temppoint == "" then -- not reading a point
+				tempbetween = tempbetween .. c
+			else
+				temppoint = temppoint .. c
+			end
+		end
+	end
+	return r
+end
+
+-- main function
+function bezierplot(functionstring,xmin,xmax,ymin,ymax)
+	local fstringreplaced = string.gsub(functionstring, "%*%*", "^")
+	local f = assert(load("local x = ...; return " .. fstringreplaced)) 
+	local isreverse = false
+	if xmin > xmax then
+		isreverse = true
+	end
+	xmin, xmax = math.min(xmin,xmax), math.max(xmin,xmax)
+	local xstep = (xmax-xmin)/20000
+	-- the output of the x coordinates will be rounded to rndx digits
+	local rndx = math.max(0,math.floor(4.5-log(xmax-xmin)/log(10)))
+	local xerror = abs(xmax-xmin)/(100*10^rndx)
+	ymin, ymax = math.min(ymin,ymax), math.max(ymin,ymax)
+	-- the output of the x coordinates will be rounded to rndy digits
+	local rndy = math.max(0,math.floor(4.5-log(ymax-ymin)/log(10)))
+	local yerror = (ymax-ymin)/(100*10^rndy)
+	-- determine parts of the graph that are inside window
+	local graphs = {}
+	local outside = true -- value is outside window
+	local i = 0
+	local j = 0
+	for n = 0, 20000 do
+		local x = xmin + n/20000*(xmax-xmin)
+		local y = f(x)
+		if y >= ymin-yerror and y <= ymax+yerror then -- inside
+			if outside then -- if it was outside before
+				outside = false
+				j = 0
+				i = i + 1
+				graphs[i] = {}
+			end
+			j = j + 1
+			graphs[i][j] = {x,y}
+		else
+			outside = true
+		end
+	end
+
+	local functiontype = "unknown"
+	local bezierstring = ""
+
+	-- go through the connected parts
+	for part = 1, #graphs do 
+		local d = diffgraph(f,graphs[part],xstep)
+		-- check for type of function (only for the first part)
+		if part == 1 then
+			if is_affine(d,yerror) then
+				functiontype = "affine"
+			elseif are_cubic(graphs,yerror) then
+				functiontype = "cubic"
+			elseif are_cuberoot(graphs,xerror) then
+				functiontype = "cuberoot"
+			end
+		end
+		if functiontype ~= "cuberoot" then -- start with initial point
+			bezierstring = bezierstring .. "(" .. round(d[1][1],rndx) 
+			.. "," 	.. round(d[1][2],rndy) .. ")"
+		end
+		if functiontype == "affine" then 
+			bezierstring = bezierstring .. " -- (" .. round(d[#d][1],
+			rndx) .. "," .. round(d[#d][2],rndy) ..")"
+		elseif functiontype == "cubic" then 
+			local startindex = 1
+			local extremainbetween = false
+			for k = 2, #d do
+				if d[k][5] then -- extrema 
+					extremainbetween = true
+					bezierstring = bezierstring 
+					.. graphtobezier(d,startindex,k,rndx,rndy,false)
+					startindex = k
+				end
+			end
+			if not extremainbetween then
+				for k = 2, #d do
+					if d[k][6] then -- inflection point
+						-- check, if the controlpoints are outside
+						-- of the bounding box defined by the vertices
+						-- (d[1][1],d[1][2]) and (d[#d][1],d[#d][2])
+						local qx = d[1][1]+(d[#d][1]-d[1][1])/3
+						local rx = d[1][1]+2*(d[#d][1]-d[1][1])/3
+						local qy = d[1][2]+(qx-d[1][1])*d[1][3]
+						local ry = d[#d][2]+(rx-d[#d][1])*d[#d][3]
+						if math.max(qy,ry) > ymax 
+						or math.min(qy,ry) < ymin then
+							bezierstring = bezierstring ..graphtobezier(
+							d,startindex,k,rndx,rndy,false)
+							startindex = k
+						end
+					end
+				end
+			end
+			if startindex ~= #d then -- if no special points inbetween
+				bezierstring = bezierstring 
+				.. graphtobezier(d,startindex,#d,rndx,rndy,false)
+			end
+		elseif functiontype == "cuberoot" then 
+			-- we determine a, b, c, d and then
+			-- get x' = 3ay^2+2by+c
+			local a, b, c, dd = parameters_cubic(
+			d[math.floor(.2*l)][2], d[math.floor(.2*l)][1],
+			d[math.floor(.4*l)][2], d[math.floor(.4*l)][1],
+			d[math.floor(.6*l)][2], d[math.floor(.6*l)][1],
+			d[math.floor(.8*l)][2], d[math.floor(.8*l)][1])
+			-- now recalculate the graph with the inverse function:
+			-- we can increase the accuracy
+			xstep = (ymax-ymin)/100000 -- inverse redefinition
+			local finverse = assert(load("local x = ...; return "
+			..a.."*x^3+"..b.."*x^2+"..c.."*x+"..dd))
+			local graphinverse = {}
+			local i = 1
+			for y = ymin, ymax, xstep do
+				local x = finverse(y)
+				if x > xmin and x < xmax -- inside
+				and abs(y-f(x)) < (ymax-ymin)/(100*10^rndy) then 
+					graphinverse[i] = {y,x}
+					i = i + 1
+				end
+			end
+			d = diffgraph(finverse,graphinverse,xstep)
+			bezierstring = bezierstring .. "(" .. round(d[1][2],rndy) 
+			.. "," .. round(d[1][1],rndx) .. ")" -- initial point
+			local startindex = 1
+			for k = 2, #d do
+				if d[k][6] then -- inflection point
+					-- check, if the controlpoints are outside
+					-- of the bounding box defined by the vertices
+					-- (d[1][1],d[1][2]) and (d[#d][1],d[#d][2])
+					local qx = d[1][1]+(d[#d][1]-d[1][1])/3
+					local rx = d[1][1]+2*(d[#d][1]-d[1][1])/3
+					local qy = d[1][2]+(qx-d[1][1])*d[1][3]
+					local ry = d[#d][2]+(rx-d[#d][1])*d[#d][3]
+					if math.max(qy,ry) > xmax 
+					or math.min(qy,ry) < xmin then
+						bezierstring = bezierstring..graphtobezier(
+						d,startindex,k,rndx,rndy,true)
+						startindex = k
+					end
+				end
+			end
+			if startindex ~= #d then -- if no special points inbetween
+				bezierstring = bezierstring 
+				.. graphtobezier(d,startindex,#d,rndx,rndy,true)
+			end
+		else	
+			-- standard case (nothing special)			
+			local startindex = 1
+			for k = 2, #d do
+				if d[k][5] or d[k][6] then -- extrema and inflection points
+					bezierstring = bezierstring .. graphtobezierapprox(
+					f,d,startindex,k,rndx,rndy,(ymax-ymin)/(0.5*10^rndy))
+					startindex = k
+				end
+			end
+			if startindex ~= #d then -- if no special points inbetween
+				bezierstring = bezierstring .. graphtobezierapprox(f,d,
+				startindex,#d,rndx,rndy,(ymax-ymin)/(0.5*10^rndy))
+			end
+		end
+	end
+	if isreverse then
+		return reversepath(bezierstring)
+	else
+		return bezierstring
+	end
+end
+
+-- main program --
+
+if not pcall(debug.getlocal, 4, 1) then
+	if #arg >= 1 then
+		local xmin = -5
+		local xmax = 5
+		if #arg >= 2 then xmin = arg[2] end
+		if #arg >= 3 then
+			if arg[3] == arg[2] then
+				xmax = xmin + 10
+			else
+				xmax = arg[3]
+			end
+		end
+		local ymin = -5
+		local ymax = 5
+		if #arg >= 4 then ymin = arg[4] end
+		if #arg >= 5 then 
+			if arg[5] == arg[4] then
+				ymax = ymin + 10
+			else
+				ymax = arg[5]
+			end
+		end
+		print(bezierplot(arg[1],xmin,xmax,ymin,ymax))
+	end
+end
+
+
+


Property changes on: trunk/Master/texmf-dist/tex/lualatex/bezierplot/bezierplot.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/lualatex/bezierplot/bezierplot.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/bezierplot/bezierplot.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/lualatex/bezierplot/bezierplot.sty	2018-05-02 17:55:49 UTC (rev 47566)
@@ -0,0 +1,17 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{bezierplot}[2018/04/12 bezierplot]
+\RequirePackage{xparse}
+\RequirePackage{iftex}
+\ifLuaTeX
+ \directlua{require("bezierplot")}
+ \DeclareExpandableDocumentCommand{\xbezierplot}{O{-5} O{5} O{-5} O{5} m}{%
+  \directlua{tex.sprint(bezierplot("#5",#1,#2,#3,#4))}
+  }
+\else
+ \let\xpandblinpt\@@input
+ \DeclareExpandableDocumentCommand{\xbezierplot}{O{-5} O{5} O{-5} O{5} m}{%
+  \xpandblinpt|"bezierplot '#5' #1 #2 #3 #4"
+ }
+\fi
+\providecommand\bezierplot{\romannumeral`\^^@\xbezierplot}
+\endinput
\ No newline at end of file


Property changes on: trunk/Master/texmf-dist/tex/lualatex/bezierplot/bezierplot.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/tlpkg/bin/tlpkg-ctan-check
===================================================================
--- trunk/Master/tlpkg/bin/tlpkg-ctan-check	2018-05-02 17:53:59 UTC (rev 47565)
+++ trunk/Master/tlpkg/bin/tlpkg-ctan-check	2018-05-02 17:55:49 UTC (rev 47566)
@@ -88,7 +88,7 @@
     beamerthemenirma
     beebe begingreek begriff beilstein belleek bengali
     bera berenisadf besjournals bestpapers betababel beton beuron
-    bewerbung bez123 bezos bgreek bgteubner bguq bhcexam
+    bewerbung bez123 bezierplot bezos bgreek bgteubner bguq bhcexam
     bib-fr bib2gls bibarts biber bibhtml
     biblatex biblatex-abnt biblatex-anonymous biblatex-apa
     biblatex-archaeology biblatex-arthistory-bonn

Modified: trunk/Master/tlpkg/libexec/ctan2tds
===================================================================
--- trunk/Master/tlpkg/libexec/ctan2tds	2018-05-02 17:53:59 UTC (rev 47565)
+++ trunk/Master/tlpkg/libexec/ctan2tds	2018-05-02 17:55:49 UTC (rev 47566)
@@ -1534,7 +1534,7 @@
 

 # packages which need special .tex/.sty files installed
 $standardtex
-   = '(\.(.bx|4ht|cls|clo|cmap|code\.tex|def|fd|fontspec|ldf|sty|trsl)'
+   = '(\.(.bx|4ht|cls|clo|cmap|code\.tex|def|fd|fontspec|ldf|lua|sty|trsl)'
     . '|.*[^c]\.cfg)$'; # not ltxdoc.cfg
 %specialtex = (
  '2up',         '2up\.tex|' . $standardtex,

Added: trunk/Master/tlpkg/tlpsrc/bezierplot.tlpsrc
===================================================================
Modified: trunk/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc	2018-05-02 17:53:59 UTC (rev 47565)
+++ trunk/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc	2018-05-02 17:55:49 UTC (rev 47566)
@@ -6,6 +6,7 @@
 depend collection-basic
 #
 depend auto-pst-pdf-lua
+depend bezierplot
 depend checkcites
 depend chickenize
 depend combofont



More information about the tex-live-commits mailing list