From 2dd820f377c1dccbc53a6d34d604b7b4a5ed317c Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 1 Aug 2011 00:48:08 +0000 Subject: pst-bspline (31jul11) git-svn-id: svn://tug.org/texlive/trunk@23294 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/generic/pst-bspline/README | 4 +- .../doc/generic/pst-bspline/pst-bspline-doc.pdf | Bin 111493 -> 142662 bytes .../doc/generic/pst-bspline/pst-bspline-doc.tex | 165 ++++++++++++++++----- .../texmf-dist/dvips/pst-bspline/pst-bspline.pro | 68 +++++++++ .../tex/generic/pst-bspline/pst-bspline.tex | 163 ++++++++++++++++++-- .../tex/latex/pst-bspline/pst-bspline.sty | 2 +- 6 files changed, 349 insertions(+), 53 deletions(-) create mode 100644 Master/texmf-dist/dvips/pst-bspline/pst-bspline.pro diff --git a/Master/texmf-dist/doc/generic/pst-bspline/README b/Master/texmf-dist/doc/generic/pst-bspline/README index 5224a25cf46..62d5a1ef35c 100644 --- a/Master/texmf-dist/doc/generic/pst-bspline/README +++ b/Master/texmf-dist/doc/generic/pst-bspline/README @@ -2,10 +2,10 @@ %% %% Michael Sharpe %% -%% Version 1.41, 2010/10/19 +%% Version 1.44, 2011/07/30 %% %% License: Free -This package draws uniform, cubic B-spline curves, open and closed, based on a sequence of B-spline control points. There is also code which permits drawing the open or closed cubic B-spline curve interpolating a sequence of points. This version adds a \thickBspline macro. +This package draws uniform, cubic B-spline curves, open and closed, based on a sequence of B-spline control points. There is also code which permits drawing the open or closed cubic B-spline curve interpolating a sequence of points. This update adds a number of macros allowing B-spline curves to be used as if they were parametric curves. The .tex and .sty files should be installed in a folder searched by TeX. All documentation is in pst-bspline-doc.pdf. \ No newline at end of file diff --git a/Master/texmf-dist/doc/generic/pst-bspline/pst-bspline-doc.pdf b/Master/texmf-dist/doc/generic/pst-bspline/pst-bspline-doc.pdf index 7b4beb03b8d..f8392d5358c 100644 Binary files a/Master/texmf-dist/doc/generic/pst-bspline/pst-bspline-doc.pdf and b/Master/texmf-dist/doc/generic/pst-bspline/pst-bspline-doc.pdf differ diff --git a/Master/texmf-dist/doc/generic/pst-bspline/pst-bspline-doc.tex b/Master/texmf-dist/doc/generic/pst-bspline/pst-bspline-doc.tex index 8e034e19af3..d88db518937 100644 --- a/Master/texmf-dist/doc/generic/pst-bspline/pst-bspline-doc.tex +++ b/Master/texmf-dist/doc/generic/pst-bspline/pst-bspline-doc.tex @@ -7,6 +7,17 @@ \usepackage{multido,pst-node,pst-bspline,pstricks-add} \usepackage{amssymb} \usepackage[parfill]{parskip} +\usepackage{lmodern} +\usepackage[scaled=.82]{luximono}%requires T1+textcomp +\usepackage[T1]{fontenc} +\newcommand\textSMC[1]{{\SMC #1}} +\newcommand\acro[1]{\textSMC{#1}\@} +\DeclareRobustCommand\cs[1]{\texttt{\char`\\#1}} +\usepackage[cal=boondoxo]{mathalfa} +\usepackage{textcomp} +%\usepackage{url} +%\def\url@ttstyle{% +% \@ifundefined{selectfont}{\def\UrlFont{\tt}}{\def\UrlFont{\ttfamily\small}}} \usepackage{hyperref} \hyphenation{Post-Script} %\date{} % Activate to display a given date or no date @@ -15,17 +26,40 @@ \large Michael Sharpe\\[10pt] msharpe@ucsd.edu} \end{center} -A cubic uniform B-spline curve with control points $B_0 \ldots B_n$ is a curve parametrized by the interval $[0,n]$, which is, except in degenerate cases, $C^2$-continuous (that is, has continuous curvature) and is on each interval $[k-1,k]$ given by a cubic B\'ezier curve whose control points are derived from the $(B_k)$. These curves are discussed in any reasonably modern text on Numerical Analysis. One easily accessible source is the UCLA lecture notes of Kirby Baker: +A cubic, uniform B-spline curve with control points $B_0 \ldots B_n$ ($n \ge 2$) is a curve parametrized by the interval $[0,n]$, which is, except in degenerate cases, $C^2$-continuous (that is, has continuous curvature) and is on each interval $[k-1,k]$ ($0\}}] defines a clipping path 12{\tt pt} wide around the B-spline curve with control points {\tt B0}..{\tt B5}, then draws the {\tt } clipped to that path. +\item[\cs{bspcurvenodes\{P\}\{Q\}}] creates a node sequence {\tt Q0} {\tt Q1},... from the position data in the arrays {\tt P.X}, {\tt P.Y}. +\end{description} +Details and examples are provided below. + +\section{Relaxed, Open B-spline} The algorithm to generate such a curve from a sequence of control points $B_0$, $\cdots$, $B_n$ is as follows: \begin{itemize} -\item The curve starts at $B_0$ and ends at $B_n$. -\item Divide each line $B_{k-1}B_k$ into equal thirds, with subdivision points labeled $R_{k-1}$, $L_k$ respectively, so that $B_k$ has $L_k$ as its immediate neighbor to the left, and $R_k$ as its immediate neighbor to the right. +\item The curve starts at $B_0$ and ends at $B_n$. (Important: $n \ge 2$.) +\item Divide each line segment $B_{k-1}B_k$ into equal thirds, with subdivision points labeled $R_{k-1}$, $L_k$ respectively, so that $B_k$ has $L_k$ as its immediate neighbor to the left, and $R_k$ as its immediate neighbor to the right. \item For $0}{} \end{verbatim} corresponding to the macros \verb|\psBspline|, \verb|\psBsplineC| and \verb|\psBsplineE|. The difference is that the macros with {\tt Nodes} in the name have as arguments the root node name and the last index, rather than the list of points. For example, with the above definition of {\tt P} in force, \verb|\psBsplineNodes{P}{2}| has exactly the same effect as \verb|\psBspline(2,1.5)(3,4)(5,1).| +\subsection{The \cs{bspcurvepoints} macros} +There are two macros that provide for B-spline curves essentially the same functionality as the \verb|\pscurvepoints| macro from {\tt pstricks-add}. (That macro takes as input a parametric curve and constructs as output (at the PostScript level) arrays of data associated with the curve: the positions of points along the curve, the increment from the previous point and a normal vector to the curve. The principal uses for such data are (i) the \verb|\pspolylineticks| macro from {\tt pstricks-add}, which allows placement of ticks and other marks along a curve that has been approximated by a polyline; (ii) the \cs{polyIntersections} macro from \textsf{pst-node}, which allows you to find the points of intersection of the curve (approximated by a polyline) and an arbitrary line.) The macros +\begin{verbatim} +\bspcurvepoints{}{}{} +\bspcurvepointsE{}{}{} +\end{verbatim} +work, in the first case, for a relaxed, uniform B-spline curve, and in the second, for such a curve with its initial and final segments removed, corresponding to the output from \verb|\psBsplineE| rather than \verb|\psBspline|. In both cases, you may set the keyword {\tt plotpoints} (default value: $50$) to change the number of sample points on each B\'ezier component. This will result in the construction of PostScript arrays with indices from $0$ to $n=$\textsf{num of segments}$\times$\textsf{(plotpoints-1)}. After running +\begin{verbatim} +\pnodes{B}(1,2)(3,-1)(4,1)(6,2)% define B0..B3 +\bspcurvepoints[plotpoint=11]{B}{3}{P} +\end{verbatim} +the following PostScript arrays are created, each indexed from 0 to 30: +\begin{verbatim} +P.X, P.Y (position) +PNormal.X, PNormal.Y (normal vector) +PDelta.X, PDelta.Y (increment from previous position) +\end{verbatim} +and these may be used in the usual way to create nodes. For example, +\begin{verbatim} +\pnode(! P.X 8 get P.Y 8 get){Q} +\pnode(! PNormal.X 8 get PNormal.Y get){Dir} +\psrline(Q)(1cm;{(Dir)}) +\end{verbatim} +places {\tt Q} at the position on the curve with index 8, defines {\tt Dir} to be a normal vector at that point, then draws a line from {\tt Q} of length {\tt 1cm} in the direction of that normal. +\subsection{Setting nodes on a B-spline curve} +To set a node at parameter value $t$ on a B-spline curve after running \cs{bspcurvepoints}{\tt[E]}, call the macro +\begin{verbatim} +\bspNode{}{}{}{} +\end{verbatim} +For example, if I have constructed a B-spline curve using control points $B_0$,$\dots$,$B_5$, then \verb|\bspNode{B}{5}{2.1}{Q}| defines a node named $Q$ at $t=2.1$. + +The macro \cs{bspcurvenodes\{P\}\{R\}} creates a node sequence {\tt R0}..{\tt Rn} at the locations specified by the arrays {\tt P.X}, {\tt P.Y}. (Those arrays must first have been created with one of the \cs{bspcurvepoints} macros.) +\subsection{B-spline function curves} +By this we mean an open B-spline curve which is the graph of a function $y=f(x)$ and whose orientation is toward the right. It is not analytically simple to specify a formula for $f$ in most cases, and to compute $y$ from $x$ involves (a) finding the index of the B\'ezier segment containing $x$; (b) solving the cubic $x(t)=x$ for $t$; (c) substituting in $y(t)$. The package provides a macro to perform these calculations after generating the data using \cs{bspcurvepoints}{\tt[E]}: +\begin{verbatim} +\bspfnNode{}{}{}{} +\end{verbatim} \section{B-spline Interpolation} This is the inverse problem. Being given points $(S_k)_{0\le k\le n}$, the goal is to produce the B-spline control points $B_k$ leading to the points $S_k$, so that the associated B-spline curve interpolates the $S_k$. @@ -206,7 +285,7 @@ for the $B_k$. In matrix form, this becomes the tridiagonal system &1&4&1\\ &&\cdots&&1\\ &&&1&4\end{pmatrix} -\begin{pmatrix}B_1\\B_2\\B_3\\ \cdots\\ B_{n-1}\end{pmatrix}=ß +\begin{pmatrix}B_1\\B_2\\B_3\\ \cdots\\ B_{n-1}\end{pmatrix}= \begin{pmatrix}6S_1-S_0\\6S_2\\6S_3\\ \cdots\\6S_{n-1}-S_{n}\end{pmatrix} \] The LU decomposition of the tridiagonal matrix may be seen to take the form @@ -263,7 +342,7 @@ for the $B_k$, $1\le k\le n$. In matrix form, this becomes the system &1&4&1\\ &&\cdots&&1\\ 1&&&1&4\end{pmatrix} -\begin{pmatrix}B_1\\B_2\\B_3\\ \cdots\\ B_{n}\end{pmatrix}=ß +\begin{pmatrix}B_1\\B_2\\B_3\\ \cdots\\ B_{n}\end{pmatrix}= \begin{pmatrix}6S_1\\6S_2\\6S_3\\ \cdots\\6S_{n}\end{pmatrix} \] Let $(x_k,y_k)=6S_k$. We perform Gaussian elimination on the matrix @@ -366,19 +445,30 @@ Slight difference between psccurve and B-spline interpolation\\ \end{center} A B-spline curve can in many cases provide a good function interpolation mechanism, but the result is not guaranteed to be the graph of a function. \begin{verbatim} -\begin{center} -\begin{pspicture}[showgrid=true](-.5,-.5)(6,4) -\psdots(0,3.5)(1,.5)(3,2.5)(4,0)(5,2)(6,.5) +\begin{pspicture}(-.5,-.5)(6,4) +\psdots(0,3.5)(1,.5)(3,2.5)(4,0)(5,2)(6,.5)% +\pnodes{S}(0,3.5)(1,.5)(3,2.5)(4,0)(5,2)(6,.5)% S0..S5 +\psBsplineInterp{S}{5}% construct SB0..SB5 +\psBsplineNodes{SB}{5}% draw B-spline with control pts SB0..SB5 +\bspcurvepoints[plotpoints=10]{SB}{5}{P} +% construct the PS arrays +\bspFnNode{SB}{5}{4.5}{QQ}% node QQ on curve at x=4.5 +\psdot[linecolor=red](QQ)% \psaxes(0,0)(-.5,-.5)(6,4) -\psbspline(0,3.5)(1,.5)(3,2.5)(4,0)(5,2)(6,.5) \end{pspicture} -\end{center} \end{verbatim} +\vspace{1pc} \begin{center} \begin{pspicture}(-.5,-.5)(6,4) -\psdots(0,3.5)(1,.5)(3,2.5)(4,0)(5,2)(6,.5) -\psbspline(0,3.5)(1,.5)(3,2.5)(4,0)(5,2)(6,.5) +\psdots(0,3.5)(1,.5)(3,2.5)(4,0)(5,2)(6,.5)% +\pnodes{S}(0,3.5)(1,.5)(3,2.5)(4,0)(5,2)(6,.5)% S0..S5 +\psBsplineInterp{S}{5}%SB0..SB5 +\psBsplineNodes{SB}{5}% draw B-spline with control pts SB0..SB5 +\bspcurvepoints[plotpoints=10]{SB}{5}{P} +% construct the PS arrays +\bspFnNode{SB}{5}{4.5}{QQ}% node QQ on curve at x=4.5 +\psdot[linecolor=red](QQ)% \psaxes(0,0)(-.5,-.5)(6,4) \end{pspicture} \end{center} @@ -386,7 +476,6 @@ A B-spline curve can in many cases provide a good function interpolation mechani \begin{verbatim} \documentclass{article} -\usepackage{graphicx} \usepackage{pstricks} \usepackage{pst-bspline,pstricks-add} \begin{document} @@ -442,7 +531,8 @@ which creates a framework of B-spline control points {\tt SB0..SB3}. (The {\tt [linestyle=none]} may be omitted if you want the curve to show.) \item Create a clipping path of specified thickness around the interpolating curve and place graphics to be clipped: \begin{verbatim} -\thickBspline[plotpoints=50,linestyle=none]{S}{3}{20pt}{\psline[linecolor=red,linestyle=solid](0,0)(6,6)}% +\thickBspline[plotpoints=50,linestyle=none]{S}{3}{20pt}% +{\psline[linecolor=red,linestyle=solid](0,0)(6,6)}% \end{verbatim} (The {\tt [linestyle=none]} controls whether the clipping path is rendered, and {\tt plotpoints} controls the number of subdivisions of each B\'ezier component. Its default value is 50.) \end{itemize} @@ -476,18 +566,20 @@ The clipping path is drawn by default positively oriented so that objects are cl \end{center} \vspace{12pt} -The \verb|\thickBspline| macro works as expected in the closed (periodic) case, taking advantage of automatic incrementing of the nodecount. +The \verb|\thickBspline| macro works as expected in the closed (periodic) case, taking advantage of automatic incrementing of the nodecount. Note that \verb|\thickBspline| interprets thickness as visual, unaffected by possible differences between {\tt xunit} and {\tt yunit}. \begin{verbatim} \documentclass{article} \usepackage{pstricks} \usepackage{pst-bspline,pstricks-add} \begin{document} +\psset{yunit=1.5cm} \begin{pspicture}[showgrid=true](-.5,-.5)(6,5) -\pnodes{S}(1,0)(5,1)(4,4)(1,3)% -\psBsplineInterpC{S}{\Snodecount}% -% defines nodes SB0, SB1, SB2 etc --- the Bspline control points +\pnodes{S}(1.5,0)(5,1)(4,4)(1,3)% +\psBsplineInterpC{S}{3}% +% defines nodes SB0, SB1, SB2, SB3, SB4 --- the Bspline control points % increments \Snodecount by 1 for future macros +% Don't use C form of \psBsplineNodes with this new \Snodecount \psBsplineNodes[linestyle=none,showpoints=false]{SB}{\Snodecount}% % Constructs the Bezier control points SBR0, SBL1, SBR1, etc \thickBspline[linestyle=none]{S}{\Snodecount}{22pt}% @@ -499,14 +591,17 @@ The \verb|\thickBspline| macro works as expected in the closed (periodic) case, \vspace{12pt} \begin{center} +\psset{yunit=1.5cm} \begin{pspicture}[showgrid=true](-.5,-.5)(6,5) -\pnodes{S}(1,0)(5,1)(4,4)(1,3)% -\psBsplineInterpC{S}{\Snodecount}% -% defines nodes SB0, SB1, SB2 etc --- the Bspline control points +\pnodes{S}(1.5,0)(5,1)(4,4)(1,3)% +\psBsplineInterpC{S}{3}% +% defines nodes SB0, SB1, SB2, SB3 --- the Bspline control points % increments \Snodecount by 1 for future macros \psBsplineNodes[linestyle=none,showpoints=false]{SB}{\Snodecount}% % Constructs the Bezier control points SBR0, SBL1, SBR1, etc -\thickBspline[linestyle=none]{S}{\Snodecount}{22pt}{\psframe[fillstyle=vlines](-1,-1)(6,6)}% +\thickBspline[linestyle=none]{S}{\Snodecount}{22pt}% +{\psframe[fillstyle=vlines](-1,-1)(6,6)}% +%{\psframe[fillstyle=solid, fillcolor=lightgray](-1,-1)(6,6)}% \end{pspicture} \end{center} diff --git a/Master/texmf-dist/dvips/pst-bspline/pst-bspline.pro b/Master/texmf-dist/dvips/pst-bspline/pst-bspline.pro new file mode 100644 index 00000000000..03cefb849ef --- /dev/null +++ b/Master/texmf-dist/dvips/pst-bspline/pst-bspline.pro @@ -0,0 +1,68 @@ +% $Id: pst-bspline.pro 2011-07-30 23:45:00Z michael $ +%% +%% PostScript prologue for pst-bspline.tex. +%% Version 1.00, 2011/07/30. +%% +%% This program can be redistributed and/or modified under the terms +%% of the LaTeX Project Public License Distributed from CTAN archives +%% in directory macros/latex/base/lppl.txt. +% +% +% +tx@Dict begin +% +% numerically stable cubic root finding +% +/cubic_roots {% solve c3*t^3+c2*t^2+c1*t+c0==0 +% call with c3 c2 c1 c0 cubic_root, return solution array roots, numroots, zroot on stack +% zroot is either (a) 2, if no solution in [0,1], or +% (b) a solution in [0,1]. + 15 dict begin % all variables are local + /numroots 0 def /roots 3 array def /zroot 2 def /epsilon 1e-6 def % + /c0 ED /c1 ED /c2 ED /c3 ED % + c3 abs epsilon lt { %quadratic case + c2 abs epsilon le { c1 abs epsilon ge { % + roots 0 c0 c1 div neg put /numroots 1 def} if }% + { %c2 neq 0 + /bb c1 dup mul def % + /q bb 4 c0 c2 mul mul sub def % + q abs epsilon lt { roots 0 c1 c2 -2 mul div put /numroots 1 def } % + { q 0.0 gt { % in fact, q>= epsilon + /q q sqrt def % + c1 0.0 lt { /q q neg def } if % + /q c1 q add -2 div def % + roots 0 q c2 div put /numroots 1 def % know |c2|>=epsilon + q abs epsilon ge { roots numroots c0 q div put /numroots numroots 1 add def } if % + } if % + } ifelse } ifelse } % + {% true cubic + /c2 c2 c3 div def /c1 c1 c3 div def /c0 c0 c3 div def % normalize + /Q c2 dup mul 3 c1 mul sub 9 div def /QQQ Q dup dup mul mul def % + /R c2 dup dup mul mul 2 mul c2 c1 9 mul mul sub 27 c0 mul add 54 div def % + /RR R dup mul def % + /c2 c2 3 div def % + RR QQQ lt {% + /theta R QQQ sqrt div Acos 3 div def % in degrees + /numroots 3 def % + /r2 Q sqrt -2 mul def % + roots 0 r2 theta cos mul c2 sub put % + roots 1 r2 theta 120 add cos mul c2 sub put % + roots 2 r2 theta 120 sub cos mul c2 sub put % + }{% One or two real roots + /r0 0 def % + /A R abs RR QQQ sub sqrt add 1 3 div exp neg def % + A abs epsilon gt { % + R 0.0 lt { /A A neg def } if % + /r0 A Q A div add def } if % + roots 0 r0 c2 sub put /numroots 1 def % + A dup mul Q sub abs A abs epsilon mul lt {% + roots numroots A c2 add neg put /numroots numroots 1 add def } if % + } ifelse % + } ifelse % + 0 1 numroots 1 sub {/j ED roots j get dup 2 mul 1 sub abs 1 le { /zroot ED } if } for % + roots numroots zroot %leave these three items on stack + end } def % +% +end % tx@Dict +% +% END pst-bspline.pro diff --git a/Master/texmf-dist/tex/generic/pst-bspline/pst-bspline.tex b/Master/texmf-dist/tex/generic/pst-bspline/pst-bspline.tex index eaea89f9b77..a16112455a1 100644 --- a/Master/texmf-dist/tex/generic/pst-bspline/pst-bspline.tex +++ b/Master/texmf-dist/tex/generic/pst-bspline/pst-bspline.tex @@ -8,13 +8,15 @@ \ifx\PSTricksLoaded\endinput \else\input pstricks \fi \ifx\PSTnodeLoaded\endinput \else\input pst-node \fi \ifx\PSTXKeyLoaded\endinput \else\input pst-xkey \fi -\def\fileversion{1.41} -\def\filedate{2010/10/19} +\def\fileversion{1.44} +\def\filedate{2011/07/29} \message{`pst-bspline' v\fileversion, \filedate\space Bspline routines for pstricks (ms)} % \edef\TheAtCode{\the\catcode`\@} \catcode`\@=11\relax \pst@addfams{pst-bspline} +\pstheader{pst-bspline.pro} + \SpecialCoor %\newcount\pst@args%used in several macros--now defined in pst-node.tex @@ -152,12 +154,12 @@ \advance\bsp@cntB by \@ne% \psbezier[arrows=-\bsp@arrowB,showpoints=false](\bsp@root S\the\bsp@cntA)% (\bsp@root R\the\bsp@cntA)(\bsp@root L\the\bsp@cntB)(\bsp@root S\the\bsp@cntB)% - \ifPst@showframe \psdot[linecolor=red](\bsp@root L\the\bsp@cntB) \fi% +% \ifPst@showframe \psdot[linecolor=red](\bsp@root L\the\bsp@cntB) \fi% \fi% end \ifbsp@closed -\ifPst@showframe% - \psdot[linecolor=red](\bsp@root R0)% - \psdot[linecolor=red](\bsp@root L\the\bsp@args)% -\fi% +%\ifPst@showframe% +% \psdot[linecolor=red](\bsp@root R0)% +% \psdot[linecolor=red](\bsp@root L\the\bsp@args)% +%\fi% \ifshowpoints% \multido{\i=0+1}{\bsp@args}{\psdot(\bsp@root S\i)}% \fi% @@ -247,7 +249,7 @@ \fi% \newcount\top@ndx \top@ndx=\top@mone% \advance\top@ndx by \@ne%number of nodes to interpolate -\ +%\ \newcount\top@mtwo \top@mtwo=\top@mone \advance\top@mtwo\m@ne% % After copying S0 to S101, \top@ndx, \top@mone, \top@mtwo are top index, top index-1, top index-two---101, 100, 99 in the example \make@mcoeff{\the\top@ndx}% @@ -307,12 +309,11 @@ \multiply\np@cnt \tw@\advance\np@cnt \tw@% count of points in array \pstVerb{ gsave tx@Dict begin % /psxu \pst@number\psxunit\space def /psyu \pst@number\psyunit\space def % - /uratio psyu psxu div def % so that perp to a, b is -b*uratio a + /uratio psyu psxu div dup mul def % so that perp to a, b is -b*uratio, a /nseg #2 def /nplotpt \psk@plotpoints\space def % /clipary #2 nplotpt mul 4 mul 4 add array def % /lindex 2 def /uindex \the\ary@max\space 1 sub def % /dt 1 \psk@plotpoints\space div def % -% /halfthck #3 2 div def % end grestore }% \multido{\iA=0+1,\iB=1+1}{#2}{% % pass control points of this segment to PostScript variables @@ -320,7 +321,6 @@ gsave tx@Dict begin % STV CP T \psGetNodeCenter{#1\iA}\space \psGetNodeCenter{#1BR\iA}\space \psGetNodeCenter{#1BL\iB}\space \psGetNodeCenter{#1\iB}\space % /bez@1.x #1\iA.x def /bez@1.y #1\iA.y def %initial point on segment - %(START) = bez@1.x = bez@1.y = SB1.x = % /bez@2.x #1BR\iA.x bez@1.x sub def %adjusted control points (less init pt) /bez@2.y #1BR\iA.y bez@1.y sub def % /bez@3.x #1BL\iB.x bez@1.x sub def % @@ -340,9 +340,9 @@ /Func % position ( bez@3x t mul bez@2x add t mul bez@1x add t mul bez@1.x add psxu mul % bez@3y t mul bez@2y add t mul bez@1y add t mul bez@1.y add psyu mul ) cvx def % -%/FuncT % tangent -% ( bez@1x t bez@2xT mul add t t bez@3xT mul mul add % -% bez@1y t bez@2yT mul add t t bez@3yT mul mul add ) cvx def +% /FuncT % tangent +% ( bez@2xT t bez@3xT mul add t mul bez@1x add % +% bez@2yT t bez@3yT mul add t mul bez@1y add ) cvx def /FuncN % unit normal times delta ( bez@2yT t bez@3yT mul add t mul bez@1y add uratio mul neg bez@2xT t bez@3xT mul add t mul bez@1x add 2 copy Pyth dup % @@ -363,7 +363,7 @@ /lindex lindex 2 add def /uindex uindex 2 sub def ){tmp@P}% }% end multido \i }% end multido \iA -% if periodic, we have to adjust 2 points so as not too leave a wege in the +% if periodic, we have to adjust 2 points so as not too leave a wedge in the % clipping region. We have to set Q_{nk} to Q_0 and R_{nk} to R_0 % R_{nk} is at position 2*nk, 2*nk+1 and Q_{nk} is at the next pair %\ifbsp@per % @@ -393,5 +393,138 @@ \fi% }% \ignorespaces}% +% +\def\bsp@setup#1#2#3#4{% +%#1=bsp root, #2=num #3=\top@ndx, #4=top@ndx-1, #4 + \pstVerb{tx@Dict begin gsave STV CP T /bsp@desc #2 array def }% +% \def\num{#2} + \multido{\iA=#4+-1,\iB=#3+-1}{#2}{%\show\num + \pstVerb{% + \psGetNodeCenter{#1S\iA}\space \psGetNodeCenter{#1R\iA}\space \psGetNodeCenter{#1L\iB}\space \psGetNodeCenter{#1S\iB}\space % + /bez@0x #1S\iA.x def /bez@0y #1S\iA.y def %initial point on segment + /bez@1x #1R\iA.x bez@0x sub 3 mul def % for position--w1=3z1 + /bez@1y #1R\iA.y bez@0y sub 3 mul def + /bez@2x #1L\iB.x bez@0x sub #1R\iA.x bez@0x sub 2 mul sub 3 mul def % w2=3(z2-2z1) + /bez@2y #1L\iB.y bez@0y sub #1R\iA.y bez@0y sub 2 mul sub 3 mul def % w2=3(z2-2z1) + /bez@3x #1S\iB.x bez@1x add #1L\iB.x 3 mul sub bez@0x 2 mul add def % w3=z3+3z1-3z2 + /bez@3y #1S\iB.y bez@1y add #1L\iB.y 3 mul sub bez@0y 2 mul add def % w3=z3+3z1-3z2 + bsp@desc \iA\space mark bez@2y 2 mul bez@3y 3 mul bez@2x 2 mul bez@3x 3 mul bez@0y % + bez@1y bez@2y bez@3y bez@0x bez@1x bez@2x bez@3x ] put }% + }% end multido + \pstVerb{ grestore end }% closed tx@Dict, which contains array named bsp@desc +}% bsp@setup +\def\bspcurvepointsE{\pst@object{bspcurvepointsE}}% +\def\bspcurvepointsE@i#1#2#3{\bspcurvepoints@ii{#1}{#2}{E}{#3}}% +\def\bspcurvepoints{\pst@object{bspcurvepoints}}% +\def\bspcurvepoints@i#1#2#3{\bspcurvepoints@ii{#1}{#2}{}{#3}}% +\def\bspcurvepoints@ii#1#2#3#4{{%optional [plotpoints=xx] +% #1=bsp root,#2=maxindex,#3=E/{},#4=root name for new PS arrays, + \pst@killglue% + \newcount\bsp@numndx + \bsp@numndx=#2 \relax% + \ifx#3E\relax + \advance \bsp@numndx \m@ne \edef\top@ndx{\the\bsp@numndx} + \advance \bsp@numndx \m@ne \edef\topm@ndx{\the\bsp@numndx}% + \else% + \edef\top@ndx{\the\bsp@numndx}% + \pst@cntc=\bsp@numndx\advance\pst@cntc \m@ne% + \edef\topm@ndx{\the\pst@cntc}% + \fi% + \pst@cntb=\bsp@numndx %\advance\pst@cntb \@ne\relax% + % set up the bsp ps array + \edef\cmd{\noexpand\bsp@setup{#1}{\the\bsp@numndx}{\top@ndx}{\topm@ndx}}\cmd% + \use@par% + \pst@cntc=\psk@plotpoints\relax%\psk@plotpoints=plotpoints-1 + \pst@cnta=\pst@cntc \multiply\pst@cnta by \pst@cntb% + \edef\bsp@nsegs{\the\bsp@numndx}%\show\bsp@nsegs% + \advance\pst@cnta by \@ne\relax%=(plotpoints-1)*nsegs+1 + \edef\@arraysize{\the\pst@cnta}% +% \show\@arraysize + \pstVerb{ tx@Dict begin % + /psxu \pst@number\psxunit\space def /psyu \pst@number\psyunit\space def % + /unitratio \pst@number\psyunit \pst@number\psxunit div def % + /unitratiosq unitratio dup mul def % + /dt 1 \psk@plotpoints\space div def % + /#4.X \@arraysize\space array def % + /#4.Y \@arraysize\space array def % + /#4Delta.X \@arraysize\space array def % + /#4Delta.Y \@arraysize\space array def % + /#4Normal.X \@arraysize\space array def % + /#4Normal.Y \@arraysize\space array def % + /theseg 0 def %\the\bsp@numndx\space 1 sub def % + bsp@desc theseg get % the first segment + /cnt 1 def % counter for arrays + dup dup dup 8 get psxu mul 4 1 roll 4 get psyu mul 3 1 roll % + 9 get exch 5 get %4 copy = = = = % initial x, y, x', y' + unitratiosq mul neg #4Normal.X 0 3 -1 roll put #4Normal.Y 0 3 -1 roll put % + 2 copy #4.Y 0 3 -1 roll put #4.X 0 3 -1 roll put % + /priory ED /priorx ED % arrays now initialized + \bsp@nsegs\space {% repeat nsegs times + bsp@desc theseg get aload pop /x3 ED /x2 ED /x1 ED /x0 ED % + /y3 ED /y2 ED /y1 ED /y0 ED % + /xT3 ED /xT2 ED /yT3 ED /yT2 ED % + /Func ( x3 t mul x2 add t mul x1 add t mul x0 add psxu mul % + y3 t mul y2 add t mul y1 add t mul y0 add psyu mul ) cvx def % + /FuncN ( yT2 t yT3 mul add t mul y1 add unitratiosq mul neg % + xT2 t xT3 mul add t mul x1 add ) cvx def % + /theseg theseg 1 add def % + /j 1 def \psk@plotpoints\space {% repeat for each plotpt + /t j dt mul def Func 2 copy 2 copy FuncN % x y x y x y xN yN + #4Normal.Y cnt 3 -1 roll put % + #4Normal.X cnt 3 -1 roll put % + #4.Y cnt 3 -1 roll put % + #4.X cnt 3 -1 roll put % x y x y on stack + priory sub #4Delta.Y cnt 3 -1 roll put % + priorx sub #4Delta.X cnt 3 -1 roll put % x y on stack + /priory ED /priorx ED /j j 1 add def /cnt cnt 1 add def } repeat % + } repeat %#4.Y == % + end }% end pstVerb + \pst@cnta=\@arraysize \relax\advance\pst@cnta \m@ne % + \expandafter\xdef \csname #4pointcount\endcsname {\the\pst@cnta}% + \typeout{Created points #40 .. #4\the\pst@cnta}% +}\ignorespaces}% +\def\bspFnNode#1#2#3#4{% +% #1=root name for B-spline control points, #2=top index +% #3=x value, #4=name of node to place at (x,f(x)) +% This works only for a bspline function graph, not a general bspline curve +\pnode(! bsp@desc length /n ED % + /x #3 def % + x bsp@desc 0 get 8 get dup /xt ED lt { /x xt def } if % + x bsp@desc n 1 sub get 8 4 getinterval aload pop add add add %endpt of last segment + dup /xt ED gt { /x xt def } if % + /j 0 def % + n {% repeat + x bsp@desc j get 8 get dup /xt ED le { exit } if /j j 1 add def % + } repeat % + j 0 gt { /j j 1 sub def } if %j is index of bezier segment containing x + bsp@desc j get dup dup dup % + 11 get exch 10 get 4 2 roll 9 get exch 8 get x sub cubic_roots % + /t ED pop pop % + t 1 gt { /t 1 def } if % zroot is the t value at which x=x(t) + x bsp@desc j get 4 4 getinterval aload pop % leaves y0, y1, y2, y3 on stack + t mul add t mul add t mul add % x y now on stack + ){#4}% +}% end bspFnNode +% +\def\bspNode#1#2#3#4{% +%src maxindex t target +\pnode(! bsp@desc length /n ED % + /t #3 def % + t 0 lt { /t 0 def } if % + t n gt { /t n def } if % clamp t to [0,n] + /j t cvi def j n eq { /j n 1 sub def } if % + /t t j sub def % t in [0,1] + bsp@desc j get dup % + 8 4 getinterval aload pop t mul add t mul add t mul add % desc[[j]] x(t) + exch 4 4 getinterval aload pop t mul add t mul add t mul add % x(t) y(t) + ){#4}% +}% end bspNode +% +\def\bspcurvenodes#1#2{% +%#1= basename for points on curve, #2=basename for nodes +\multido{\iA=0+1}{\csname #1pointcount\endcsname}{% +\pnode(! #1.X \iA\space get #1.Y \iA\space get ){#2\iA}}% +}% +% \catcode`\@=\TheAtCode\relax \endinput \ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/pst-bspline/pst-bspline.sty b/Master/texmf-dist/tex/latex/pst-bspline/pst-bspline.sty index 1dabf7aafc8..07f3483441e 100644 --- a/Master/texmf-dist/tex/latex/pst-bspline/pst-bspline.sty +++ b/Master/texmf-dist/tex/latex/pst-bspline/pst-bspline.sty @@ -1,5 +1,5 @@ \ProvidesPackage{pst-bspline} - [2010/10/19 v1.41 LaTeX wrapper for pst-bspline (MS)] + [2011/06/13 v1.42 LaTeX wrapper for pst-bspline (MS)] \input{pst-bspline} \ProvidesFile{pst-bspline.tex} [\filedate\space \fileversion\space `pst-bspline' (ms)] -- cgit v1.2.3