diff options
-rwxr-xr-x | Build/cdbuild/ctan2tds.pl | 2 | ||||
-rw-r--r-- | Master/texmf-dist/doc/metapost/splines/README | 44 | ||||
-rw-r--r-- | Master/texmf-dist/doc/metapost/splines/splines.pdf | bin | 0 -> 103753 bytes | |||
-rw-r--r-- | Master/texmf-dist/metapost/splines/splines.mp | 139 | ||||
-rw-r--r-- | Master/texmf-dist/metapost/splines/testsplines.mp | 122 | ||||
-rw-r--r-- | Master/texmf-dist/source/metapost/splines/splines.dtx | 393 | ||||
-rw-r--r-- | Master/texmf-dist/source/metapost/splines/splines.ins | 48 | ||||
-rw-r--r-- | Master/texmf-dist/tpm/splines.tpm | 30 | ||||
-rw-r--r-- | Master/texmf/lists/splines | 9 | ||||
-rw-r--r-- | Master/texmf/tpm/collection-metapost.tpm | 1 |
10 files changed, 788 insertions, 0 deletions
diff --git a/Build/cdbuild/ctan2tds.pl b/Build/cdbuild/ctan2tds.pl index 1998f61cf55..de288004554 100755 --- a/Build/cdbuild/ctan2tds.pl +++ b/Build/cdbuild/ctan2tds.pl @@ -417,6 +417,7 @@ $standardfoundry='public'; 'pstricks', 'generic', 'ruhyphen', 'generic', 'skaknew', 'metapost', + 'splines', 'metapost', 'thumbpdf', 'generic', 'trajan', 'fonts', 'velthuis', 'fonts', @@ -525,6 +526,7 @@ $standardfmt='latex'; 'plnfss', 'plain', 'pxfonts', 'fonts', 'shapepar', 'generic', + 'splines', 'metapost', 'texsis', 'texsis', 'thumbpdf', 'generic', 'trajan', 'fonts', diff --git a/Master/texmf-dist/doc/metapost/splines/README b/Master/texmf-dist/doc/metapost/splines/README new file mode 100644 index 00000000000..20998c92f1e --- /dev/null +++ b/Master/texmf-dist/doc/metapost/splines/README @@ -0,0 +1,44 @@ +Splines -- version 0.2a
+
+This package consists of a few macros useful for producing cubic splines
+in MetaPost (or Metafont).
+
+Given a sequence of N+1 points, a spline is a path $z = f(t)$, $0 \le t
+\le N$, connecting them, which is a cubic function of $t$ between
+points, and has continuous first and second derivatives.
+
+Such a spline is two dimensional and can wander about anywhere in the
+picture plane. Another type of spline is one dimensional: given a
+sequence of $N$ locations $x_0 < x_1 < \dots < x_N$ on the $x$-axis and
+corresponding values $y_j$, a cubic spline interpolant is a function $y
+= f(x)$ satisfying $f(x_j) = y_j$, which is cubic between the $x_j$ and
+which has continuous first and second derivatives.
+
+With these macros one can draw two-dimensional cubic splines and the
+graphs of cubic spline interpolants.
+
+The files of this package consist of:
+ splines.dtx The documented source code.
+ splines.ins LaTeX this to produce the file splines.mp.
+ splines.pdf The documentation.
+ testsplines.mp Uses the macros to produce a few splines.
+ README The file you are reading
+
+The files of this package are Copyright 2002--2005, Daniel H. Luecking
+
+Splines.mp may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3 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.3 or later is part of all distributions of LaTeX version
+2003/12/01 or later.
+
+Splines has maintenance status "author-maintained". The Current
+Maintainer is Daniel H. Luecking. The Base Interpreter is MetaPost
+(or Metafont).
+
+You may email problem reports to luecking {at} uark {dot} edu.
+
+--
+Dan Luecking
diff --git a/Master/texmf-dist/doc/metapost/splines/splines.pdf b/Master/texmf-dist/doc/metapost/splines/splines.pdf Binary files differnew file mode 100644 index 00000000000..55604fa53a4 --- /dev/null +++ b/Master/texmf-dist/doc/metapost/splines/splines.pdf diff --git a/Master/texmf-dist/metapost/splines/splines.mp b/Master/texmf-dist/metapost/splines/splines.mp new file mode 100644 index 00000000000..c725c8b3b93 --- /dev/null +++ b/Master/texmf-dist/metapost/splines/splines.mp @@ -0,0 +1,139 @@ +%% +%% This is file `splines.mp', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% splines.dtx (with options: `package') +%% +%% ------------------------------------------------------------------- +%% +%% Copyright 2002--2005, Daniel H. Luecking +%% +%% Splines.mp may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License, either version 1.3 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.3 or later is part of all distributions of LaTeX version +%% 2003/12/01 or later. +%% +%% Splines has maintenance status "author-maintained". The Current Maintainer +%% is Daniel H. Luecking. The Base Interpreter is MetaPost (or Metafont). +%% +if known splines_fileversion: endinput fi; +string splines_fileversion; +splines_fileversion := "2006/09/25, v0.2a"; +message "Loading splines.mp " & splines_fileversion; + +def list_to_array (suffix arr) (text list) = + arr := 0; + for _itm = list : + arr[incr arr] := _itm; + endfor +enddef; + +def compute_spline (expr closed) (suffix points, pr, po) = + % interior equations: + for j= 2 upto points - 1 : + % equate first derivatives: + po[j] + pr[j] = 2 points[j]; + % and second derivatives: + pr[j+1] + 2 pr[j] = 2 po[j] + po[j-1]; + endfor + % for a closed curve, the first and last are also interior: + if closed: + po 1 + pr 1 = 2 points 1; + po[points] + pr[points] = 2 points[points]; + pr 2 + 2 pr 1 = 2 po 1 + po[points]; + pr 1 + 2 pr[points] = 2 po[points] + po[points-1]; + fi +enddef; + +vardef mksplinepath (expr closed) (suffix points, pr, po) = + points1..controls po1 and + for j = 2 upto points if not closed: -1 fi: + pr[j]..points[j]..controls po[j] and + endfor + if closed: pr 1..cycle else: pr[points]..points[points] fi +enddef; + +vardef mkrelaxedspline (suffix pnts) = + save rs_pr, rs_po; + pair rs_po[], rs_pr[]; + % Equate second derivative to zero at both end points + rs_pr 2 + pnts 1 = 2 rs_po 1 ; + pnts[pnts] + rs_po[pnts-1] = 2 rs_pr[pnts]; + compute_spline (false) (pnts, rs_pr, rs_po); + mksplinepath (false) (pnts, rs_pr, rs_po) +enddef; + +vardef mkclosedspline (suffix pnts) = + save cs_pr, cs_po; + pair cs_pr[], cs_po[]; + compute_spline (true) (pnts, cs_pr, cs_po); + mksplinepath (true) (pnts, cs_pr, cs_po) +enddef; + +vardef dospline (expr closed) (text the_list) = + save _sp; pair _sp[]; + list_to_array (_sp) (the_list); + if closed : + mkclosedspline (_sp) + else: + mkrelaxedspline (_sp) + fi +enddef; + +def compute_fcnspline (suffix points, dx, sl) = + % Get delta_x: + for j = 1 upto points - 1: dx[j] := xpart (points[j+1]-points[j]); + endfor + for j=2 upto points - 1: + sl[j + 1] * dx[j] + 2sl[j]*(dx[j] + dx[j-1]) + sl[j-1]*dx[j-1] + = 3*ypart(points[j+1] - points[j-1]); + endfor +enddef; + +vardef mkfcnsplinepath (suffix points, dx, sl) = + points1..controls (points1 + (1, sl1)*dx1/3) and + for j = 2 upto points - 1: + (points[j] - (1, sl[j])*dx[j-1]/3) ..points[j].. + controls (points[j] + (1,sl[j])*dx[j]/3) and + endfor + (points[points] - (1,sl[points])*dx[points-1]/3)..points[points] +enddef; + +vardef mkperiodicfcnspline (suffix pnts) = + save _sl, _dx; numeric _dx[], _sl[]; + compute_fcnspline (pnts, _dx, _sl); + % periodicity equations: + _sl 1 = _sl[pnts]; + _sl 2 * _dx 1 + 2 _sl 1 * _dx 1 + 2 _sl[pnts] * _dx[pnts-1] + + _sl[pnts-1] * _dx[pnts-1] + = 3 * ypart(pnts[2] - pnts[pnts-1]); + mkfcnsplinepath (pnts, _dx, _sl) +enddef; + +vardef mkrelaxedfcnspline (suffix pnts) = + save _sl, _dx; numeric _dx[], _sl[]; + compute_fcnspline (pnts, _dx, _sl); + % relaxation equations. + _sl 2 * _dx 1 + 2 _sl1 * _dx 1 = 3 * ypart(pnts2 - pnts1); + _sl[pnts-1] * _dx[pnts-1] + 2 _sl[pnts] * _dx[pnts-1] + = 3 * ypart(pnts[pnts] - pnts[pnts-1]); + mkfcnsplinepath (pnts, _dx, _sl) +enddef; + +vardef fcnspline (expr periodic) (text the_list) = + save _fs; pair _fs[]; + list_to_array (_fs) (the_list); + if periodic: + mkperiodicfcnspline (_fs) + else: + mkrelaxedfcnspline (_fs) + fi +enddef; + +endinput. +%% +%% End of file `splines.mp'. diff --git a/Master/texmf-dist/metapost/splines/testsplines.mp b/Master/texmf-dist/metapost/splines/testsplines.mp new file mode 100644 index 00000000000..a6ad01d0adb --- /dev/null +++ b/Master/texmf-dist/metapost/splines/testsplines.mp @@ -0,0 +1,122 @@ +input splines; + +numeric u; u:=1cm; + +path xaxis, yaxis; +xaxis := (-2.5u,0)--(1.5u,0); +yaxis := (0,-.5u)--(0,1.5u); + +def shiftit = + currentpicture := currentpicture shifted -llcorner currentpicture; +enddef; + +def dodots (text t) = + for _loc = t: + fill (fullcircle scaled 2pt) shifted (u*_loc); + endfor +enddef; + + + +beginfig(1); + drawarrow xaxis; + drawarrow yaxis; + path p; + p := dospline (true) + ((-1,0), (-1,1), (-.5,.8), (0,1),(.5,.4), (1,0), (1.5,1)); + draw p scaled u; +label(btex From {\tt dospline (true)}. etex,(.25u,-.75u)); +dodots ((-1,0), (-1,1), (-.5,.8), (0,1),(.5,.4), (1,0), (1.5,1)); +shiftit; +endfig; + +beginfig(2); + drawarrow xaxis; + drawarrow yaxis; + save A; pair A[]; + list_to_array (A)((-1,0), (-1,1), (-.5,.8), (0,1),(.5,.4), (1,0), (1.5,1)); + path p; + p := mkclosedspline (A); + draw p scaled u; +label(btex From {\tt mkclosedspline}. etex,(.25u,-.75u)); +dodots (A1, A2, A3, A4, A5, A6, A7); +shiftit; +endfig; + +beginfig(3); + drawarrow xaxis; + drawarrow yaxis; + path p; + p := dospline (false) + ((-1,0), (-1,1), (-.5,.8), (0,1),(.5,.4), (1,0), (1.5,1)); + draw p scaled u; +label(btex From {\tt dospline (false)}. etex,(.25u,-.75u)); +dodots ((-1,0), (-1,1), (-.5,.8), (0,1),(.5,.4), (1,0), (1.5,1)); +shiftit; +endfig; + +beginfig(4); + drawarrow xaxis; + drawarrow yaxis; + save A; pair A[]; + list_to_array (A)((-1,0), (-1,1), (-.5,.8), (0,1),(.5,.4), (1,0), (1.5,1)); + path p; + p := mkrelaxedspline (A); + draw p scaled u; +label(btex From {\tt mkrelaxedspline}. etex,(.25u,-.75u)); +dodots (A1, A2, A3, A4, A5, A6, A7); +shiftit; +endfig; + +beginfig(5); + drawarrow xaxis; + drawarrow yaxis; + path p; + p := fcnspline (true) + ((-2,0), (-1,1), (-.5,.8), (0,1),(.5,.4), (1,0), (1.5,1)); + draw p scaled u; +label(btex From {\tt fcnspline (true)}. etex,(.25u,-.75u)); +dodots ((-2,0), (-1,1), (-.5,.8), (0,1),(.5,.4), (1,0), (1.5,1)); +shiftit; +endfig; + +beginfig(6); + drawarrow xaxis; + drawarrow yaxis; + save A; pair A[]; + list_to_array(A) ((-2,0), (-1,1), (-.5,.8), (0,1),(.5,.4), (1,0), (1.5,1)); + path p; + p := mkperiodicfcnspline (A); + draw p scaled u; +label(btex From {\tt mkperiodicfcnspline}. etex,(.25u,-.75u)); +dodots (A1, A2, A3, A4, A5, A6, A7); +shiftit; +endfig; + +beginfig(7); + drawarrow xaxis; + drawarrow yaxis; + path p; + p := fcnspline (false) + ((-2,0), (-1,1), (-.5,.8), (0,1),(.5,.4), (1,0), (1.5,1)); + draw p scaled u; +label(btex From {\tt fcnspline (false)}. etex,(.25u,-.75u)); +dodots((-2,0), (-1,1), (-.5,.8), (0,1),(.5,.4), (1,0), (1.5,1)); +shiftit; +endfig; + +beginfig(8); + drawarrow xaxis; + drawarrow yaxis; + save A; pair A[]; + list_to_array(A) ((-2,0), (-1,1), (-.5,.8), (0,1),(.5,.4), (1,0), (1.5,1)); + path p; + p := mkrelaxedfcnspline (A); + draw p scaled u; +label(btex From {\tt mkrelaxedfcnspline}. etex,(.25u,-.75u)); +dodots (A1, A2, A3, A4, A5, A6, A7); +shiftit; +endfig; + +end. + diff --git a/Master/texmf-dist/source/metapost/splines/splines.dtx b/Master/texmf-dist/source/metapost/splines/splines.dtx new file mode 100644 index 00000000000..da89dda74d6 --- /dev/null +++ b/Master/texmf-dist/source/metapost/splines/splines.dtx @@ -0,0 +1,393 @@ +% \iffalse +% ------------------------------------------------------------------- +% +% Copyright 2002--2004, Daniel H. Luecking +% +% Splines.mp may be distributed and/or modified under the conditions of the +% LaTeX Project Public License, either version 1.3 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.3 or later is part of all distributions of LaTeX version +% 2003/12/01 or later. +% +% Splines has maintenance status "author-maintained". The Current Maintainer +% is Daniel H. Luecking. The Base Interpreter is MetaPost (or Metafont). +% +%<*driver> +\ProvidesFile{splines.dtx} + [2005/02/05 v0.2 Metafont/post macros to compute splines.]% +\documentclass[draft]{ltxdoc} +\usepackage{docmfp} + +\addtolength{\textwidth}{.5878pt} + +\def\mytt{\upshape\mdseries\ttfamily} +\renewcommand\marg[1]{{\mytt \{#1\}}} +\renewcommand\oarg[1]{{\mytt [#1]}} +\renewcommand\parg[1]{{\mytt (#1)}} +\renewcommand{\meta}[1]{{$\langle$\rmfamily\itshape#1$\rangle$}} +\DeclareRobustCommand\cs[1]{{\mytt\char`\\#1}} +\def\prog#1{{\mdseries\scshape #1}} + + + + +\def\MF{\prog{meta\-font}} +\def\MP{\prog{meta\-post}} + +\def\CMF{\prog{Meta\-font}} +\def\CMP{\prog{Meta\-post}} +\def\opt#1{{\sffamily\upshape#1}} +\def\mfc#1{{\mytt#1}} +\let\env\mfc +\let\file\mfc +\let\gbc\mfc +\renewcommand\{{{\mytt\char`\{}} +\renewcommand\}{{\mytt\char`\}}} +\renewcommand\|{${}\mathrel{|}{}$} + +\makeatletter +\newcommand\bsl{{\mytt\@backslashchar}} +% Stupid lists! +\def\@listi{\leftmargin\leftmargini + \parsep \z@ \@plus\p@ \@minus\z@ + \topsep 4\p@ \@plus\p@ \@minus2\p@ + \itemsep\parsep} +\let\@listI\@listi \@listi +\renewcommand\labelitemi{\normalfont\bfseries \textendash} +\renewcommand\labelitemii{\textasteriskcentered} +\renewcommand\labelitemiii{\textperiodcentered} +\leftmargini\parindent +% Stupid index! +\def\usage#1{\textrm{#1}} +\def\index@prologue{\section*{Index}\markboth{Index}{Index}Numbers +refer to the page where the corresponding entry is described.} +\def\IndexParms{% + \parindent \z@ \columnsep 15pt + \parskip 0pt plus 1pt + \rightskip 5pt plus2em \mathsurround \z@ + \parfillskip=-5pt \small + % less hanging: + \def\@idxitem{\par\hangindent 20pt}% + \def\subitem{\@idxitem\hspace*{15pt}}% + \def\subsubitem{\@idxitem\hspace*{25pt}}% + \def\indexspace{\par\vspace{10pt plus 2pt minus 3pt}}} +\renewcommand\routinestring{} +\renewcommand\variablestring{\space(var.)} +% Why does every command have to be indexed twice? +\renewcommand\SpecialMfpIndex[3]{\@bsphack + \index{% + \string#1\actualchar + \string\verb\quotechar*\verbatimchar\string#1\verbatimchar + #2 \encapchar usage}% + \@esphack} +\def\close@crossref{\SpecialEscapechar{:}} +\makeatother +\def\VariableIndex#1{\SpecialMfpIndex{#1}{\variablestring}{}} +\def\RoutineIndex #1{\SpecialMfpIndex{#1}{}{}} + +\title{Macros to Compute Splines\thanks{This file has version number + \fileversion, last revised \filedate.}} +\author{Dan Luecking} +\date{\filedate} +\SpecialEscapechar{:} +\def\bslash{:} +\DisableCrossrefs +\CodelineIndex +\AlsoImplementation + +\begin{document} + \DeleteShortVerb{\|} + \DocInput{splines.dtx} +\end{document} +%</driver> +%\fi +% +% \CheckSum{25} +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% \catcode`\_=12 +% \GetFileInfo{splines.dtx} +% \maketitle +% +% \StopEventually{\PrintIndex} +% A cubic spline through a set of points is a curve obtained by joining +% each point to the next with a cubic parametrized curve, where adjoining +% cubics must have matching first and second derivative at their common +% point. +% +% It is possible for \MP{} to compute the necessary controls. +% Unfortunately, the controls are not uniquely determined unless the curve +% is required to be closed. For open curves, there is need for two +% additional equations at the end points. A `relaxed spline' is produced +% if we require that the second derivative is $(0,0)$ at those points. +% For a closed curve, the equality of the first and second derivatives at +% the common beginning/ending point gives the needed additional equations. +% +% Note that this equates \emph{time} derivatives, so this works best when +% points are relatively evenly spaced and so the speed is relatively +% uniform. If points are differently spaced then the relatively slower +% speed between closely spaced points allows sharper turns without large +% second derivatives. Curves produced tend to have a more natural look, +% and relaxed splines are most suitable for smoothing data that is +% obtained by taking observations at evenly spaced times. Still, the +% technique is somewhat unstable when points are closely spaced, for +% example when a small change in the position of one point can produce a +% large change in its direction when viewed from another point. +% +% Start with version control information. +% \begin{macrocode} +%<*package> +if known splines_fileversion: endinput fi; +string splines_fileversion; +splines_fileversion := "2006/09/25, v0.2a"; +message "Loading splines.mp " & splines_fileversion; + +% \end{macrocode} +% +% \DescribeRoutine{list_to_array} +% Now for a command that takes a variable name \gbc{(suffix arr)} and +% copies a list of pairs to \mfc{arr1}, \mfc{arr2}, etc.. +% The suffix must be declared by the calling program so that \mfc{arr} +% is numeric but \mfc{arr[\,]} are pairs, for example by ``\mfc{save arr; pair +% arr[\,];}''. +% \begin{macrocode} +def list_to_array (suffix arr) (text list) = + arr := 0; + for _itm = list : + arr[incr arr] := _itm; + endfor +enddef; + +% \end{macrocode} +% +% \DescribeRoutine{compute_spline} +% In this command we generate the equations common to all cubic +% splines: the equality of derivatives at all interior points. +% This command accepts three suffixes: \gbc{points}, \gbc{pr}, and +% \gbc{po} which should represent previously declared arrays of pairs. +% \gbc{points} is the array of points to be connected, and must be known. +% Arrays \gbc{pr} and \gbc{po} \emph{must} be unknown and will hold the +% computed control points. See the code of \mfc{mkrelaxedspline} for +% an example of how this was arranged for the variables \mfc{rs_pr} and +% \mfc{rs_po}. +% +% Contrary to the previous (unreleased) version, \mfc{compute_spline} +% takes a boolean argument and appends the same equations at the first (= +% last) point. +% +% \DescribeRoutine{mkrelaxedspline} +% The first of these macros appends the necessary additional equations to +% get zero second derivatives at the ends. +% \DescribeRoutine{mkclosedspline} +% The second simply calls \mfc{compute_spline} with the boolean set to +% true. Both return the computed path. In theory the knowledgeable user +% can call \gbc{compute_spline (false)}, append a choice of equations for +% the ends, and then call \gbc{mksplinepath (false)}. +% +% \DescribeRoutine{dospline} +% This version accepts a list of pairs and produces a spline through +% them. It simply stores the list in an array and calls the appropriate +% version that operates on an array. +% \begin{macrocode} +def compute_spline (expr closed) (suffix points, pr, po) = + % interior equations: + for j= 2 upto points - 1 : + % equate first derivatives: + po[j] + pr[j] = 2 points[j]; + % and second derivatives: + pr[j+1] + 2 pr[j] = 2 po[j] + po[j-1]; + endfor + % for a closed curve, the first and last are also interior: + if closed: + po 1 + pr 1 = 2 points 1; + po[points] + pr[points] = 2 points[points]; + pr 2 + 2 pr 1 = 2 po 1 + po[points]; + pr 1 + 2 pr[points] = 2 po[points] + po[points-1]; + fi +enddef; + +vardef mksplinepath (expr closed) (suffix points, pr, po) = + points1..controls po1 and + for j = 2 upto points if not closed: -1 fi: + pr[j]..points[j]..controls po[j] and + endfor + if closed: pr 1..cycle else: pr[points]..points[points] fi +enddef; + +vardef mkrelaxedspline (suffix pnts) = + save rs_pr, rs_po; + pair rs_po[], rs_pr[]; + % Equate second derivative to zero at both end points + rs_pr 2 + pnts 1 = 2 rs_po 1 ; + pnts[pnts] + rs_po[pnts-1] = 2 rs_pr[pnts]; + compute_spline (false) (pnts, rs_pr, rs_po); + mksplinepath (false) (pnts, rs_pr, rs_po) +enddef; + +vardef mkclosedspline (suffix pnts) = + save cs_pr, cs_po; + pair cs_pr[], cs_po[]; + compute_spline (true) (pnts, cs_pr, cs_po); + mksplinepath (true) (pnts, cs_pr, cs_po) +enddef; + +vardef dospline (expr closed) (text the_list) = + save _sp; pair _sp[]; + list_to_array (_sp) (the_list); + if closed : + mkclosedspline (_sp) + else: + mkrelaxedspline (_sp) + fi +enddef; + +% \end{macrocode} +% The above computations produce a $2$-dimensional spline. A $1$-dimensional +% cubic spline would be a function $f(t)$ with numeric values rather +% than pair values. Such are often used to interpolate functions. That is, +% given pairs $(x\sb j,y\sb{j})$, and assuming they lie on the graph of +% some function (generally unknown), fill in the graph with $y = f(x)$ +% where $f$ is a cubic function of $x$ in each interval $x\sb j < x < x\sb +% {j+1}$, making sure that the resulting graph is as smooth as possible at +% the points $x\sb j$. +% +% The requirements on our $2$-dimensional path are the following: +% \begin{enumerate} +% \item The $j$th link should connect $(x\sb{j},y\sb{j})$ to $(x\sb{j+1}, +% y\sb{j+1})$. +% \item The $x$-part of that link should increase linearly from $x\sb{j}$ to +% $x\sb{j+1}$ as $t$ goes from $0$ to $1$. +% \item The $y$-part should be a cubic $y = f(x)$. +% \item The $x$-derivatives $df/dx$ and $d^2f/dx^2$ should match at the +% connecting points. +% \end{enumerate} +% +% Two necessary equations for converting between $x$ and $t$ coordinates +% are: +% \begin{equation}\label{first} +% x = x\sb{j} + t \Delta x\sb{j} +% \end{equation} +% (where $\Delta x\sb{j} = x\sb{j+1} - x\sb{j}$) and +% \begin{equation}\label{second} +% \frac{df}{dt} = \frac{dx}{dt}\frac{df}{dx} = (x\sb{j+1} - +% x\sb{j}) \frac{df}{dx}. +% \end{equation} +% Thus we want to choose controls so that (\ref{first}) is maintained and +% so that $x$-derivatives match. It turns out that this requires controls +% at +% \begin{equation} +% \begin{array}{c} +% (x\sb{j}, y\sb{j}) - (\Delta x\sb{j-1}, s\sb{j} \Delta x\sb{j-1})/3\\ +% (x\sb{j}, y\sb{j}) + (\Delta x\sb{j} , s\sb{j} \Delta x\sb{j} )/3 +% \end{array} +% \end{equation} +% where $s\sb{j}$ is the slope (derivative) at $x\sb{j}$. These control +% points will produce matching slopes regardless of the values +% chosen for the $s\sb j$. To get matching second derivatives we need the +% same conditions as in parametric splines. But those equations simplify +% to the form: +% \begin{displaymath} +% s\sb{j+1} dx\sb{j} - 2s\sb{j} (dx\sb{j} + dx\sb{j-1}) + +% s\sb{j-1}dx\sb{j-1} +% = 3y\sb{j+1} - 3y\sb{j-1}. +% \end{displaymath} +% As with 2-D splines there can be almost any equations at the end points. +% For a relaxed spline we equate the second derivatives to 0. To get a +% periodic function, we equate the slope and second derivative at +% beginning to those at the end. This makes it possible to put a shifted +% copy of the graph with starting point at the end of the original and +% have the same smoothness at that connection as at the other points. +% +% \DescribeRoutine{compute_fcnspline} +% This issues the equation for the slopes (array \gbc{sl} of +% \emph{unknown} numerics). The array \gbc{points} contains the $(x,y)$ +% values and \gbc{dx} is a temporary numeric array which will be +% overwritten if known. +% +% \DescribeRoutine{mkfcnsplinepath} +% This simply assembles the path from the information computed by the +% above equations (and the extra equations given in the calling command). +% +% \DescribeRoutine{mkrelaxedfcnspline} +% This sets up arrays for the \gbc{dx} and \gbc{sl} parameters of +% \mfc{compute_fcnspline}, emit the necessary endpoint equations (zero +% second derivatives) and calls the previous two routines. +% +% \DescribeRoutine{mkperiodicfcnspline} +% This does the same as the previous command, but the endpoint equations +% make the first and second derivatives at the start equal to those at +% the end. +% +% \DescribeRoutine{fcnspline} +% Finally, this command copies a list of pairs into an array and calls the +% appropriate command to process them. +% \begin{macrocode} +def compute_fcnspline (suffix points, dx, sl) = + % Get delta_x: + for j = 1 upto points - 1: dx[j] := xpart (points[j+1]-points[j]); + endfor + for j=2 upto points - 1: + sl[j + 1] * dx[j] + 2sl[j]*(dx[j] + dx[j-1]) + sl[j-1]*dx[j-1] + = 3*ypart(points[j+1] - points[j-1]); + endfor +enddef; + +vardef mkfcnsplinepath (suffix points, dx, sl) = + points1..controls (points1 + (1, sl1)*dx1/3) and + for j = 2 upto points - 1: + (points[j] - (1, sl[j])*dx[j-1]/3) ..points[j].. + controls (points[j] + (1,sl[j])*dx[j]/3) and + endfor + (points[points] - (1,sl[points])*dx[points-1]/3)..points[points] +enddef; + +vardef mkperiodicfcnspline (suffix pnts) = + save _sl, _dx; numeric _dx[], _sl[]; + compute_fcnspline (pnts, _dx, _sl); + % periodicity equations: + _sl 1 = _sl[pnts]; + _sl 2 * _dx 1 + 2 _sl 1 * _dx 1 + 2 _sl[pnts] * _dx[pnts-1] + + _sl[pnts-1] * _dx[pnts-1] + = 3 * ypart(pnts[2] - pnts[pnts-1]); + mkfcnsplinepath (pnts, _dx, _sl) +enddef; + +vardef mkrelaxedfcnspline (suffix pnts) = + save _sl, _dx; numeric _dx[], _sl[]; + compute_fcnspline (pnts, _dx, _sl); + % relaxation equations. + _sl 2 * _dx 1 + 2 _sl1 * _dx 1 = 3 * ypart(pnts2 - pnts1); + _sl[pnts-1] * _dx[pnts-1] + 2 _sl[pnts] * _dx[pnts-1] + = 3 * ypart(pnts[pnts] - pnts[pnts-1]); + mkfcnsplinepath (pnts, _dx, _sl) +enddef; + +vardef fcnspline (expr periodic) (text the_list) = + save _fs; pair _fs[]; + list_to_array (_fs) (the_list); + if periodic: + mkperiodicfcnspline (_fs) + else: + mkrelaxedfcnspline (_fs) + fi +enddef; + +%</package> +% \end{macrocode} +% \clearpage +%\Finale diff --git a/Master/texmf-dist/source/metapost/splines/splines.ins b/Master/texmf-dist/source/metapost/splines/splines.ins new file mode 100644 index 00000000000..ac047affa34 --- /dev/null +++ b/Master/texmf-dist/source/metapost/splines/splines.ins @@ -0,0 +1,48 @@ +\input docstrip +\keepsilent +\preamble + +------------------------------------------------------------------- + +Copyright 2002--2005, Daniel H. Luecking + +Splines.mp may be distributed and/or modified under the conditions of the +LaTeX Project Public License, either version 1.3 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.3 or later is part of all distributions of LaTeX version +2003/12/01 or later. + +Splines has maintenance status "author-maintained". The Current Maintainer +is Daniel H. Luecking. The Base Interpreter is MetaPost (or Metafont). + +\endpreamble +\edef\zyx{% +endinput.^^J% +\DoubleperCent^^J% +\DoubleperCent\space End of file `\outFileName'.} + +\askforoverwritefalse +\usepostamble\zyx +\generate{\file{splines.mp}{\from{splines.dtx}{package}}} + +\def\sJ{^^J \space\space\space} +\immediate\write16{% +^^J******************************************************************* +^^J +^^J To finish the installation: +^^J +^^J -- Copy the file splines.mp to a location where MetaPost +\sJ will find it, for example TEXMF/metapost/splines/ . +^^J +^^J -- If desired, copy splines.mp to a location where Metafont will +\sJ find it, e.g., TEXMF/metafont/splines/ . Rename it splines.mf. +^^J +^^J -- To generate the documentation, run latex on splines.dtx (requires +\sJ the package docmfp). +^^J +^^J -- Refresh the filename database if your TeX system requires it. +^^J +^^J*******************************************************************} + +\endbatchfile diff --git a/Master/texmf-dist/tpm/splines.tpm b/Master/texmf-dist/tpm/splines.tpm new file mode 100644 index 00000000000..4468aa5efd0 --- /dev/null +++ b/Master/texmf-dist/tpm/splines.tpm @@ -0,0 +1,30 @@ +<!DOCTYPE rdf:RDF SYSTEM "../../support/tpm.dtd"> +<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:TPM="http://texlive.dante.de/"> + <rdf:Description about="http://texlive.dante.de/texlive/Package/splines.zip"> + <TPM:Name>splines</TPM:Name> + <TPM:Type>Package</TPM:Type> + <TPM:Date>2006/09/25 21:39:00</TPM:Date> + <TPM:Version></TPM:Version> + <TPM:Creator>karl</TPM:Creator> + <TPM:Title>The splines package.</TPM:Title> + <TPM:Description></TPM:Description> + <TPM:Author></TPM:Author> + <TPM:Size>128780</TPM:Size> + <TPM:Build/> + <TPM:RunFiles size="8100"> +texmf-dist/metapost/splines/splines.mp +texmf-dist/metapost/splines/testsplines.mp +texmf-dist/tpm/splines.tpm + </TPM:RunFiles> + <TPM:DocFiles size="105600"> +texmf-dist/doc/metapost/splines/README +texmf-dist/doc/metapost/splines/splines.pdf + </TPM:DocFiles> + <TPM:SourceFiles size="16159"> +texmf-dist/source/metapost/splines/splines.dtx +texmf-dist/source/metapost/splines/splines.ins + </TPM:SourceFiles> + <TPM:Provides>Package/splines</TPM:Provides> + </rdf:Description> +</rdf:RDF> + diff --git a/Master/texmf/lists/splines b/Master/texmf/lists/splines new file mode 100644 index 00000000000..eb317003008 --- /dev/null +++ b/Master/texmf/lists/splines @@ -0,0 +1,9 @@ +texmf-dist/doc/metapost/splines/README +texmf-dist/doc/metapost/splines/splines.pdf +texmf-dist/source/metapost/splines/splines.dtx +texmf-dist/source/metapost/splines/splines.ins +texmf-dist/metapost/splines/splines.mp +texmf-dist/metapost/splines/testsplines.mp +texmf-dist/tpm/splines.tpm + +texmf/lists/splines diff --git a/Master/texmf/tpm/collection-metapost.tpm b/Master/texmf/tpm/collection-metapost.tpm index f1179a4eacb..95bb2123edb 100644 --- a/Master/texmf/tpm/collection-metapost.tpm +++ b/Master/texmf/tpm/collection-metapost.tpm @@ -32,6 +32,7 @@ <TPM:Package name="piechartmp"/> <TPM:Package name="roex"/> <TPM:Package name="slideshow"/> + <TPM:Package name="splines"/> <TPM:TLCore name="bin-metapost"/> <TPM:TLCore name="collection-basic"/> </TPM:Requires> |