From fbbfbf6dd1459939387d20e98c9b5ab8c8b8fc4c Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 17 Mar 2014 22:55:23 +0000 Subject: pst-intersect (17mar14) git-svn-id: svn://tug.org/texlive/trunk@33210 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/pst-intersect/Changes | 7 +- .../doc/latex/pst-intersect/pst-intersect-DE.pdf | Bin 114227 -> 118799 bytes .../doc/latex/pst-intersect/pst-intersect.pdf | Bin 111359 -> 114544 bytes .../dvips/pst-intersect/pst-intersect.pro | 358 ++++++++--- .../source/latex/pst-intersect/pst-intersect.dtx | 714 +++++++++++++++------ .../source/latex/pst-intersect/pst-intersect.ins | 2 +- .../tex/generic/pst-intersect/pst-intersect.tex | 105 +-- .../tex/latex/pst-intersect/pst-intersect.sty | 6 +- 8 files changed, 838 insertions(+), 354 deletions(-) diff --git a/Master/texmf-dist/doc/latex/pst-intersect/Changes b/Master/texmf-dist/doc/latex/pst-intersect/Changes index 6433af63488..603885d2e00 100644 --- a/Master/texmf-dist/doc/latex/pst-intersect/Changes +++ b/Master/texmf-dist/doc/latex/pst-intersect/Changes @@ -1,3 +1,8 @@ +0.4 2014-03-16 + * Added \psGetCurvePoint. + * Fixed \pstracecurve for use with \pscustom. + * Fixed arrow behavior. + 0.3 2014-03-04 * Fixed \psGetIsectNode to work with more than one segment. * Modified \psGetIsectNode and the naming conventions of the @@ -9,7 +14,7 @@ * Added support for arrows parameter to \pstracecurve. * Modified parameters tstart, tstop, istart and istop to respect different directions. - * Added macro \psGetIsectCenter + * Added \psGetIsectCenter * Fixed a bug in the termination of the iteration procedure. * Fixed a bug in the point order of Bézier curves, which was related to a now fixed bug in pst-func. diff --git a/Master/texmf-dist/doc/latex/pst-intersect/pst-intersect-DE.pdf b/Master/texmf-dist/doc/latex/pst-intersect/pst-intersect-DE.pdf index bb9f0969637..47bdc753a65 100644 Binary files a/Master/texmf-dist/doc/latex/pst-intersect/pst-intersect-DE.pdf and b/Master/texmf-dist/doc/latex/pst-intersect/pst-intersect-DE.pdf differ diff --git a/Master/texmf-dist/doc/latex/pst-intersect/pst-intersect.pdf b/Master/texmf-dist/doc/latex/pst-intersect/pst-intersect.pdf index 2a613d0c4dc..467a296483f 100644 Binary files a/Master/texmf-dist/doc/latex/pst-intersect/pst-intersect.pdf and b/Master/texmf-dist/doc/latex/pst-intersect/pst-intersect.pdf differ diff --git a/Master/texmf-dist/dvips/pst-intersect/pst-intersect.pro b/Master/texmf-dist/dvips/pst-intersect/pst-intersect.pro index d6a7521a745..900934684b6 100644 --- a/Master/texmf-dist/dvips/pst-intersect/pst-intersect.pro +++ b/Master/texmf-dist/dvips/pst-intersect/pst-intersect.pro @@ -9,7 +9,7 @@ %% This is a generated file. %% %% Project: pst-intersect -%% Version: 0.3 (2014/03/04) +%% Version: 0.4 (2014/03/16) %% %% Copyright (C) 2007-2014 by Christoph Bersch %% @@ -40,7 +40,7 @@ tx@IntersectDict begin /VecScale { dup 4 -1 roll mul 3 1 roll mul } bind def -/ToVec { +/ToPnt { [ 3 1 roll ] } bind def /MaxPrecision 1e-6 def @@ -50,7 +50,7 @@ tx@IntersectDict begin /H2Interval [0.5 MaxPrecision add 1] def /IntersectBeziers { 2 copy length 2 eq exch length 2 eq and { - IntersectLines + IntersectLineSegms }{ 2 copy [0 1] [0 1] IterateIntersection } ifelse @@ -63,24 +63,87 @@ tx@IntersectDict begin 8 -2 roll 2 copy 10 4 roll 4 2 roll 2 copy 6 2 roll 10 2 roll VecSub 6 2 roll 4 2 roll VecSub - 8 4 roll 4 2 roll VecSub % X3-X4 Y3-Y4 X2-X1 Y2-Y1 X3-X1 Y3-Y1 % b1 b2 a1 a2 c1 c2 + 8 4 roll 4 2 roll VecSub 6 copy 12 -4 roll neg 4 -1 roll mul 3 1 roll mul add dup 0 eq { - % no intersections 9 { pop } repeat [] [] } { dup 10 1 roll 5 1 roll 4 -1 roll mul 3 1 roll mul sub exch div 6 1 roll 4 -1 roll mul 3 1 roll mul sub exch div - 2 copy 2 copy 0 ge exch 0 ge and 3 1 roll 1 le exch 1 le and and { - [ exch ] exch [ exch ] - } { - pop pop [] [] - } ifelse - } ifelse + [ exch ] exch [ exch ] + } ifelse + DebugEnd +} bind def +/IntersectLineSegms { + IntersectLines + dup length 0 eq not { + 0 get exch 0 get + 2 copy 2 copy 0 ge exch 0 ge and 3 1 roll 1 le exch 1 le and and { + [ exch ] exch [ exch ] + } { + pop pop [] [] + } ifelse + } if +} bind def +/IntersectLineLineSegm { + tx@IntersectDict begin IntersectLines end + dup length 0 eq not { + 0 get dup dup 0 ge exch 1 le and { + [ exch ] + } { + pop pop [] [] + } ifelse + } if + 3 -1 roll exch +} bind def +/IntersectLinePath { + (IntersectLinePath) DebugBegin + 3 dict begin + PreparePath + 2 copy ElongateLine exch 3 -1 roll pop + /isect [] def + /t -1 def + /n -1 def + { + /n n 1 add def + 2 copy IntersectBeziers + dup 5 1 roll LoadIntersectionPoints + dup length 0 gt { + /isect exch def + 0 get aload pop add 0.5 mul n add /t exch def + exch pop + exit + } { + pop pop pop + } ifelse + } forall + t isect + end DebugEnd } bind def +/ElongateLine { + exch { aload pop } forall + 4 2 roll 2 copy 6 2 roll + VecSub 0 5 1 roll + 6 -1 roll { + { + aload pop + 6 2 roll 4 copy 10 4 roll + 6 2 roll VecSub 4 2 roll + tx@EcldDict begin Project end + tx@Dict begin Pyth end + 6 -1 roll 2 copy + gt { pop } { exch pop } ifelse + 5 1 roll + } forall + } forall + % for a line + 5 -1 roll VecScale 4 copy VecSub ToPnt 5 1 roll VecAdd ToPnt ToPnt + % for a ray + %4 2 roll 2 copy ToPnt 6 1 roll 4 2 roll 5 -1 roll 1.1 mul VecScale VecAdd ToPnt ToPnt +} bind def /IntersectPaths { (IntersectPaths) DebugBegin 6 dict begin @@ -106,7 +169,6 @@ tx@IntersectDict begin } forall pop % remove [pathA] [ isect { aload pop } forall ] 3 1 roll tA exch tB - % [intersections] [pathA] [tA] [pathB] [tB] end DebugEnd } bind def @@ -116,39 +178,72 @@ tx@IntersectDict begin 2 copy PreparePath dup length /n exch def /isect [] def /tA [] def /tB [] def - { % [curveA] [Bi] + { /n n 1 sub def - exch dup 3 -1 roll % [curveA] [curveA] [Bi] + exch dup 3 -1 roll IntersectBeziers - 4 copy LoadIntersectionPoints % [curveA] [tA] [curveB] [tB] + 4 copy LoadIntersectionPoints [ exch isect aload pop ] /isect exch def pop 3 -1 roll pop [ tB aload length 2 add -1 roll TArray { n add } forall ] /tB exch def [ tA aload length 2 add -1 roll TArray aload pop ] /tA exch def } forall - pop % remove [curveA] + pop [ isect { aload pop } forall ] 3 1 roll tA exch tB - % [intersections] [curveA] [tA] [pathB] [tB] end DebugEnd } bind def /IntersectPathCurve { exch IntersectCurvePath 4 2 roll } bind def +/MergeAndSortArrays { + [ 3 1 roll aload pop counttomark -1 roll aload pop ] + dup length 0 gt { + dup dup 0 get type /arraytype eq { + hulldict /comp get + } { + /lt + } ifelse + exch quicksort + } if +} bind def /SaveIntersection { (SaveIntersection) DebugBegin - 4 dict dup 10 -1 roll exch def - begin % - /Points 6 -1 roll def - 5 -1 roll dup 4 -1 roll def % /curveA [curveA] [tA] [tB] /curveB /curveB [curveB] def - nametostr (@t) strcat cvn exch TArray def % /curveA [curveA] [tA] /curveB@t [tB] def - 3 -1 roll dup 4 -1 roll def - nametostr (@t) strcat cvn exch TArray def - end + exch dup 3 1 roll % isectname add? isectname + currentdict exch known and { + load begin % pnts A tA B tB /A /B + dup currentdict exch known { % /nameB already saved. + 4 -1 roll pop % pnts A tA tB /A /B + nametostr (@t) strcat cvn dup load 4 -1 roll + MergeAndSortArrays def + } { + dup 5 -1 roll def % pnts A tA B tB /A /B + nametostr (@t) strcat cvn 3 -1 roll TArray def + } ifelse % pnts A tA /A + dup currentdict exch known { % /nameB already saved. + 3 -1 roll pop + nametostr (@t) strcat cvn dup load 3 -1 roll + MergeAndSortArrays def + } { + dup 4 -1 roll def + nametostr (@t) strcat cvn exch TArray def + } ifelse + /Points exch ArrayToPointArray Points ArrayToPointArray + MergeAndSortArrays PointArrayToArray def + end + } { + 4 dict dup 3 1 roll def + begin + dup 5 -1 roll def + nametostr (@t) strcat cvn 3 -1 roll TArray def + dup 4 -1 roll def + nametostr (@t) strcat cvn exch TArray def + /Points exch def + end + } ifelse DebugEnd } bind def /TArray { - (TArray) DebugBegin dup length 0 gt { dup 0 get type /arraytype eq { [ exch @@ -158,37 +253,64 @@ tx@IntersectDict begin } if dup /lt exch quicksort } if - DebugEnd %1 debug } bind def /InitTracing { /movetype /moveto load def /linetype /lineto load def /curvetype /curveto load def } bind def -InitTracing /GetFullPath { + (GetFullPath) DebugBegin { /movetype counttomark 3 roll } { /linetype counttomark 3 roll } { /curvetype counttomark 7 roll }{} pathforall + DebugEnd +} bind def +/ReversePath { + gsave newpath + [ exch aload pop InitTracing + { counttomark 0 eq { exit } if + load exec + } loop + reversepath + GetFullPath ] + grestore +} bind def +/ReverseCurve { + PointArrayToArray aload pop % [ tstart tstop [ X0 Y0 X1 Y1... + counttomark -2 4 { 2 roll } for ] ArrayToPointArray +} bind def +/ReverseInterval { + 3 -1 roll dup 4 1 roll GetSegmentCount + dup 4 1 roll exch sub 3 1 roll sub exch +} bind def +/UnifyInterval { + exch dup 0 lt { pop 0 } if exch + 3 -1 roll dup 4 1 roll GetSegmentCount + 2 copy exch dup 3 1 roll % [curve] tstart tstop cnt tstop cnt tstop + lt exch 0 lt or { exch } if pop % (tstop < 0 | cnt < tstop) } bind def /PreparePath { + (PreparePath) DebugBegin [ exch aload pop { dup type /nametype eq not { exit } if dup /movetype eq { - pop ToVec /@mycp exch def + pop ToPnt /@mycp exch def } { dup /linetype eq { - pop [ @mycp 4 2 roll 2 copy ToVec /@mycp exch def ToVec ] + pop [ @mycp 4 2 roll 2 copy ToPnt /@mycp exch def ToPnt ] } { - pop [ @mycp 8 2 roll 2 copy ToVec /@mycp exch def - ToVec 5 1 roll ToVec 4 1 roll ToVec 3 1 roll ] + pop [ @mycp 8 2 roll 2 copy ToPnt /@mycp exch def + ToPnt 5 1 roll ToPnt 4 1 roll ToPnt 3 1 roll ] } ifelse counttomark 1 roll } ifelse } loop ] + DebugEnd } bind def /GetSegmentCount { + (GetSegmentCount) DebugBegin dup IsPath { [ exch aload pop 0 { @@ -207,8 +329,9 @@ InitTracing exch pop } { % a Bezier curve is a single segment - pop 1 + length 0 gt { 1 } { 0 } ifelse } ifelse + DebugEnd } bind def /LoadLineIntersectionPoints { (LoadLineIntersectionPoints) DebugBegin @@ -226,7 +349,6 @@ InitTracing [ exch { aload pop } forall ] exch [ exch { aload pop } forall ] } repeat - % [A0.x A0.y ... AM.x AM.y] [tA0a tA0b ... tAMa tAMb] [tB0a tB0b ... tBNa tBNb] [B0.x B0.y ... BN.x BN.y] tx@Dict begin tx@FuncDict begin 2 dict begin dup length 2 idiv 1 sub /BezierType exch def /Points exch def [ exch { GetBezierCoor } forall ] @@ -234,15 +356,12 @@ InitTracing dup length 2 idiv 1 sub /BezierType exch def /Points exch def [ exch { GetBezierCoor } forall ] end - %2 debug - % [IB0.xa IB0.ya IB0.xb IB0.yb ... IBM.yb] [IA0.xa IA0.ya IA0.xb IA0.yb ... IAM.yb] 2 { [ exch aload length 4 idiv { [ 5 1 roll ] counttomark 1 roll } repeat ] exch } repeat - % [[IB0.xa ...] ... [... IBM.yb]] [[IA0.xa IA0.ya IA0.xb IA0.yb] ...[IAM.xa ... IAM.yb]] 2 { dup hulldict /comp get exch quicksort exch } repeat @@ -253,16 +372,7 @@ InitTracing 2 copy aload pop VecSub Pyth exch aload pop VecSub Pyth lt { exch } if pop aload pop VecAdd 0.5 VecScale - } for - % merge near intersection points - %counttomark 2 idiv 1 1 3 -1 roll { - % pop - % counttomark 4 lt { exit } if - % 4 copy 4 2 roll ToVec 3 1 roll ToVec AreNear { - - % } - %} for - ] + } for ] end end end DebugEnd @@ -328,14 +438,13 @@ domsB domsA /depth depth 1 add def /dom null def /counter counter 1 add def - CheckIT { (>> curve subdivision performed: dom(A) = ) domA CurveToString strcat (, dom(B) = ) strcat domB CurveToString strcat ( <<) strcat == } if CurveA IsConstant CurveB IsConstant and { -CurveA MiddlePoint ToVec -CurveB MiddlePoint ToVec AreNear { +CurveA MiddlePoint ToPnt +CurveB MiddlePoint ToPnt AreNear { domA domB 4 -1 roll exch PutInterval PutInterval } { pop pop @@ -350,8 +459,8 @@ domB Extent precision ge or and not { iter 100 ge { false } { -CurveA MiddlePoint ToVec -CurveB MiddlePoint ToVec AreNear { +CurveA MiddlePoint ToPnt +CurveB MiddlePoint ToPnt AreNear { domA domB true }{ false @@ -364,7 +473,6 @@ CheckIT { (, iter: ) iter 20 string cvs strcat strcat (, depth: ) depth 20 string cvs strcat strcat == } if - CurveA CurveB ClipCurve /dom exch def CheckIT {(dom : ) dom CurveToString strcat == } if @@ -388,8 +496,8 @@ CurveB IsConstant CurveA IsConstant and { (C1: [ ) CurveA { CurveToString ( ) strcat strcat } forall (]) strcat == (C2: [ ) CurveB { CurveToString ( ) strcat strcat } forall (]) strcat == } if - CurveA MiddlePoint ToVec - CurveB MiddlePoint ToVec AreNear { + CurveA MiddlePoint ToPnt + CurveB MiddlePoint ToPnt AreNear { domA domB true } { false @@ -472,7 +580,7 @@ CheckIT { ToUnitRange exch ToUnitRange 2 copy gt { exch } if - ToVec + ToPnt } bind def /ToUnitRange { dup 0 lt { @@ -489,7 +597,7 @@ CloneVec } forall ] } bind def /CloneVec { - aload pop ToVec + aload pop ToPnt } bind def /MapTo { (MapTo) DebugBegin @@ -556,7 +664,7 @@ exch sub 0 1 3 -1 roll % L-1 t [CurveB] 0 1 L-i-1 3 -1 roll dup 1 exch sub 3 1 roll % [A] (1-t) [B] t exch aload pop 3 -1 roll VecScale % [A] (1-t) B.x*t B.y*t 4 2 roll - exch aload pop 3 -1 roll VecScale VecAdd ToVec % [A.x*(1-t)+B.x*t A.y*(1-t)+B.y*t] + exch aload pop 3 -1 roll VecScale VecAdd ToPnt % [A.x*(1-t)+B.x*t A.y*(1-t)+B.y*t] DebugEnd } bind def /IsConstant { @@ -750,80 +858,85 @@ pop dup length 1 sub get type /nametype eq { true } { false } ifelse } bind def /ShowPathPortion { - 6 dict begin + (ShowPathPortion) DebugBegin + 8 dict begin /tstop exch def /tstart exch def + /savecp { ToPnt cvx /@cp exch def } def InitTracing /n 0 def mark exch aload pop { - counttomark 0 eq n tstop ge or { pop exit } if + counttomark 0 eq n tstop ge or { cleartomark exit } if dup /movetype eq not { /n n 1 add def } if - dup /movetype eq { - load exec + pop savecp } { - tstart n gt { + tstart n ge { /curvetype eq { 6 2 roll 4 { pop } repeat } if - movetype + savecp } { tstart n 1 sub gt tstop n lt or { tstart n sub 1 add tstop n sub 1 add ToUnitInterval exch /linetype eq { - 3 1 roll ToVec currentpoint ToVec exch ToVec + 3 1 roll ToPnt + tstart n 1 sub gt { @cp ToPnt } { currentpoint ToPnt } ifelse exch ToPnt dup 3 -1 roll Portion aload pop exch tstart n 1 sub gt { exch aload pop 3 -1 roll aload pop ArrowA tstop n le { - currentpoint 4 2 roll ArrowB lineto pop pop + currentpoint 4 2 roll ArrowB linetype pop pop } { - lineto + linetype } ifelse } { - pop aload pop currentpoint 4 2 roll ArrowB lineto pop pop + pop aload pop currentpoint 4 2 roll ArrowB linetype pop pop } ifelse } { - 7 1 roll [ currentpoint 9 3 roll ] ArrayToPointArray - dup 3 -1 roll Portion + 7 1 roll + [ tstart n 1 sub gt { @cp }{ currentpoint } ifelse + 9 3 roll ] ArrayToPointArray + dup 3 -1 roll + Portion { aload pop } forall - 8 -2 roll - tstart n 1 sub gt { moveto } { pop pop } ifelse - 6 -2 roll currentpoint ArrowA 6 2 roll - tstop n le { - ArrowB - } if - curveto + tstart n 1 sub gt { + 8 -4 roll 4 2 roll ArrowA 6 2 roll + } { + 8 -2 roll pop pop + } ifelse + tstop n le { ArrowB } if + curvetype } ifelse }{ tstart n 1 sub eq { /linetype eq { - currentpoint ArrowA + @cp ArrowA tstop n eq { - currentpoint 4 2 roll ArrowB lineto pop pop + currentpoint 4 2 roll ArrowB linetype pop pop } { - lineto + linetype } ifelse } { - 6 -2 roll currentpoint ArrowA 6 2 roll + 6 -2 roll @cp ArrowA 6 2 roll tstop n eq { ArrowB } if - curveto + curvetype } ifelse } { /linetype eq { tstop n eq { - currentpoint 4 2 roll ArrowB lineto pop pop + currentpoint 4 2 roll ArrowB linetype pop pop }{ - lineto + linetype } ifelse } { tstop n eq { ArrowB } if - curveto + curvetype } ifelse } ifelse } ifelse @@ -831,6 +944,81 @@ pop } ifelse } loop end + DebugEnd +} bind def +/GetCurvePoint { + dup IsPath { + 5 dict begin + exch dup /tstart exch def + 1 add cvi /tstop exch def + /savecp { ToPnt cvx /@cp exch def } def + /n 0 def + mark exch aload pop + { + counttomark 0 eq n tstop ge or { cleartomark exit } if + dup /movetype eq not { /n n 1 add def } if + dup /movetype eq { + pop savecp + } { + tstart n ge { + /curvetype eq { 6 2 roll 4 { pop } repeat } if + savecp + } { + tstart n 1 sub gt { + tstart n sub 1 add tstop n sub 1 add + ToUnitInterval exch + /linetype eq { + 3 1 roll ToPnt + tstart n 1 sub gt { @cp ToPnt } { currentpoint ToPnt } ifelse exch ToPnt + dup 3 -1 roll Portion + } { + 7 1 roll + [ @cp 9 3 roll ] ArrayToPointArray + dup 3 -1 roll + Portion + } ifelse + 0 get aload pop + }{ + /curvetype eq { + pop pop pop pop + } if + } ifelse + counttomark 1 add 2 roll cleartomark exit + } ifelse + } ifelse + } loop + end + } { + exch dup 0 eq { + pop 0 get aload pop + } { + 0 exch ToUnitInterval exch dup 3 -1 roll Portion + dup length 1 sub get aload pop + } ifelse + } ifelse +} bind def +/TraceCurveOrPath { + 4 1 roll + UnifyInterval + 3 -1 roll dup IsPath { + 4 -1 roll pop + 3 1 roll 2 copy gt { + ReverseInterval + 3 -1 roll ReversePath 3 1 roll + } if + ShowPathPortion + }{ % tstart tstop [curve] + mark exch 4 2 roll % [ [curve] tstart tstop + 2 copy gt { % tstart > tstop + exch + [ 4 -1 roll ReverseCurve 3 1 roll % [ [curve'] tstart tstop + } if + ToUnitInterval exch dup 3 -1 roll Portion + { aload pop } forall + counttomark -2 4 { 2 roll } for + counttomark 2 sub 2 idiv + counttomark 2 add -1 roll exec + } ifelse } bind def % Graham Scal algorithm to compute the convex hull of a set of % points. Code written by Bill Casselman, diff --git a/Master/texmf-dist/source/latex/pst-intersect/pst-intersect.dtx b/Master/texmf-dist/source/latex/pst-intersect/pst-intersect.dtx index e1082f148c3..89900ec97ec 100644 --- a/Master/texmf-dist/source/latex/pst-intersect/pst-intersect.dtx +++ b/Master/texmf-dist/source/latex/pst-intersect/pst-intersect.dtx @@ -18,7 +18,7 @@ %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{pst-intersect} %<*stylefile> - [2014/03/04 v0.3 package wrapper for pst-intersect.tex] + [2014/03/16 v0.4 package wrapper for pst-intersect.tex] % % %<*driver> @@ -593,8 +593,9 @@ % % \ifGERMAN % \section{Anforderungen} -% \LPack{pst-intersect} benötigt aktuelle Versionen der -% Pakete \LPack{pstricks}, \LPack{pst-node} und \LPack{pst-func}. +% \LPack{pst-intersect} benötigt aktuelle Versionen der Pakete +% \LPack{pstricks}, \LPack{pst-node}, \LPack{pst-eucl} und +% \LPack{pst-func}. % % Alle PSTricks-Pakete machen regen Gebrauch von der Postscript-Sprache, so % dass der typische Arbeitsfluss \opt{latex}, \opt{dvips} und @@ -604,8 +605,8 @@ % \fi % \ifENGLISH % \section{Requirements} -% \LPack{pst-intersect} requires recent versions of -% \LPack{pstricks}, \LPack{pst-node}, and \LPack{pst-func}. +% \LPack{pst-intersect} requires recent versions of \LPack{pstricks}, +% \LPack{pst-node}, \LPack{pst-eucl} and \LPack{pst-func}. % % All PSTricks package rely heavily on the Postscript language so that the % typical workflow involves \opt{latex}, \opt{dvips}, and \opt{ps2pdf}. Of @@ -1053,6 +1054,30 @@ % % \fi % +% \begin{ltxsyntax} +% \cmditem{psGetCurvePoint}{curvename}{t} +% +% \ifGERMAN +% Speichert die Koordinaten der Kurve \prm{curvename} am Punkt \prm{t}. +% \fi +% \ifENGLISH +% Save the coordinates of \prm{curvename} at the point \prm{t}. +% \fi +% \end{ltxsyntax} +% \iffalse +%<*ignore> +% \fi +\begin{LTXexample} +\begin{pspicture}(3,3) + \pssavebezier{A}(0,0)(0,3)(3,0)(3,3) + \multido{\r=0+0.1}{11}{% + \psdot(! \psGetCurvePoint{A}{\r} I-A.x I-A.y)} +\end{pspicture} +\end{LTXexample} +% \iffalse +% +% \fi +% % \ifGERMAN % \section{Darstellung gespeicherter Schnitte} % \fi @@ -1293,6 +1318,11 @@ % % \begin{changelog} % \patchcmd{\release}{\setlength{\itemsep}{0pt}}{\setlength{\itemsep}{0pt}\setlength{\parsep}{0pt}}{}{} +% \begin{release}{0.4}{2014-03-16} +% \item Added \cs{psGetCurvePoint}. +% \item Fixed \cs{pstracecurve} for use with \cs{pscustom}. +% \item Fixed arrow behavior. +% \end{release} % \begin{release}{0.3}{2014-03-04} % \item Fixed \cs{psGetIsectNode} to work with more than one segment. % \item Modified \cs{psGetIsectNode} and the naming conventions of the @@ -1304,7 +1334,7 @@ % \item Added support for \opt{arrows} parameter to \cs{pstracecurve}. % \item Modified parameters \opt{tstart}, \opt{tstop}, \opt{istart} % and \opt{istop} to respect different directions. -% \item Added macro \cs{psGetIsectCenter} +% \item Added \cs{psGetIsectCenter} % \item Fixed a bug in the termination of the iteration procedure. % \item Fixed a bug in the point order of Bézier curves, which was % related to a now fixed bug in \opt{pst-func}. @@ -1331,7 +1361,7 @@ \input{pst-intersect.tex} \IfFileExists{pst-intersect.pro}{% \ProvidesFile{pst-intersect.pro} - [2014/03/04 PostScript prologue file] + [2014/03/16 PostScript prologue file] \@addtofilelist{pst-intersect.pro}}{}% % \end{macrocode} % @@ -1376,6 +1406,8 @@ }% \newif\PIT@saveintersections \define@boolkey[psset]{intersect}[PIT@]{saveintersections}[true]{} +\newif\PIT@addintersections +\define@boolkey[psset]{intersect}[PIT@]{addintersections}[true]{} \psset[intersect]{% tstart=-1, @@ -1383,7 +1415,8 @@ istart=-1, istop=-1, name={}, - saveintersections + saveintersections, + addintersections=false }% % \end{macrocode} % @@ -1523,51 +1556,18 @@ \PIT@checkname{#1}% \addto@pscode{% \pst@intersectdict - \PIT@key@tstop\space dup 0 lt { pop \PIT@name{#1} GetSegmentCount } if - \PIT@key@tstart\space dup 0 lt { pop 0 } if exch - \PIT@name{#1} GetSegmentCount - 2 copy exch dup 3 1 roll - lt exch 0 lt or { exch } if pop - \PIT@name{#1} dup IsPath { - 3 1 roll 2 copy gt { -% \end{macrocode} -% reverse the path, draw everything and resave the path -% \begin{macrocode} - exch 3 -1 roll dup 4 1 roll GetSegmentCount - dup 4 1 roll exch sub 3 1 roll sub exch - gsave newpath - [ 4 -1 roll aload pop InitTracing - { counttomark 0 eq { exit } if - load exec - } loop - reversepath - GetFullPath ] 3 1 roll - grestore - } if - ShowPathPortion - }{ - [ exch dup 5 -2 roll - 2 copy gt { - exch - 2 copy gt { exch } if - [ 5 -2 roll pop PointArrayToArray aload pop - counttomark -2 4 { 2 roll } for ] ArrayToPointArray dup - 4 2 roll - } if - ToUnitInterval Portion - { aload pop } forall -% \end{macrocode} -% reverse the point order -% \begin{macrocode} - counttomark -2 4 { 2 roll } for - counttomark 2 sub 2 idiv - \psk@plotpoints - exch + /\PIT@name{#1} currentdict exch known not { + (You haven't defined the curve '#1') == + } if + \PIT@name{#1} \PIT@key@tstart\space\PIT@key@tstop\space % [curve] tstart tstop + {\psk@plotpoints exch \txFunc@BezierCurve \ifshowpoints \txFunc@BezierShowPoints \else pop \fi - } ifelse + } + TraceCurveOrPath end }% + %\showpointsfalse \end@OpenObj }% % \end{macrocode} @@ -1583,7 +1583,7 @@ /\PIT@name{\PIT@name@default} \else /\PIT@name{#1} - \fi + \fi dup currentdict exch known not { \ifx\\#1\\% (You haven't defined an intersection!) == @@ -1602,56 +1602,20 @@ } { \PIT@key@tstart } ifelse - dup 0 lt { pop 0 } if exch % [curve] t_istart|tstart [ts] - % dup length \PIT@key@istop\space ge 0 \PIT@key@istop\space lt and { \PIT@key@istop\space cvi 1 sub get } { pop \PIT@key@tstop - } ifelse - 3 -1 roll dup 4 1 roll GetSegmentCount - 2 copy exch dup 3 1 roll % [curve] tstart tstop cnt tstop cnt tstop - lt exch 0 lt or { exch } if pop % (tstop < 0 | cnt < tstop) - 3 -1 roll dup - IsPath { - 3 1 roll - 2 copy gt { - exch 3 -1 roll dup 4 1 roll GetSegmentCount - dup 4 1 roll exch sub 3 1 roll sub exch -% \end{macrocode} -% reverse the path, draw everything and resave the path -% \begin{macrocode} - gsave newpath - [ 4 -1 roll aload pop InitTracing - { counttomark 0 eq { exit } if - load exec - } loop - reversepath - GetFullPath ] 3 1 roll - grestore - } if - ShowPathPortion - }{ - [ exch dup 5 -2 roll - exch dup 0 lt { pop 0 } if exch - dup 0 lt { pop 1 } if - 2 copy gt { - exch - [ 5 -2 roll pop PointArrayToArray aload pop - counttomark -2 4 { 2 roll } for ] ArrayToPointArray dup - 4 2 roll - } if - ToUnitInterval Portion - { aload pop } forall - counttomark 2 sub 2 idiv - \psk@plotpoints - exch + } ifelse % [curve] tstart tstop + {\psk@plotpoints exch \txFunc@BezierCurve \ifshowpoints \txFunc@BezierShowPoints \else pop \fi - } ifelse + } + TraceCurveOrPath end }% + %\showpointsfalse \end@OpenObj }% % \end{macrocode} @@ -1692,7 +1656,8 @@ 4 copy LoadIntersectionPoints 5 1 roll } ifelse } ifelse - /\PIT@@name\space /\PIT@name{#1} /\PIT@name{#2} 8 3 roll + /\PIT@name{#1} /\PIT@name{#2} /\PIT@@name + \ifPIT@addintersections true \else false \fi SaveIntersection }% \ifPIT@saveintersections @@ -1761,6 +1726,19 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\psGetCurvePoint} +% \begin{macrocode} +\def\psGetCurvePoint#1#2{% + \pst@intersectdict + currentdict /\PIT@name{#1} known not { + (You haven't defined the curve or path '#1') == + } if + #2 \PIT@name{#1} GetCurvePoint \tx@UserCoor + end + /I-#1.y exch def /I-#1.x exch def +}% +% \end{macrocode} +% \end{macro} % \begin{macrocode} \catcode`\@=\PstAtCode\relax % \end{macrocode} @@ -1834,14 +1812,14 @@ tx@IntersectDict begin % \end{macrocode} % \end{macro} % -% \begin{macro}{ToVec} +% \begin{macro}{ToPnt} % Convert two numbers to a procedure holding the two values. This % representation is used to save coordinate values of nodes and vectors. % \begin{pssyntax} -% \PSvar{X Y} \PSop{ToVec} \PSarray{X Y} +% \PSvar{X Y} \PSop{ToPnt} \PSarray{X Y} % \end{pssyntax} % \begin{macrocode} -/ToVec { +/ToPnt { [ 3 1 roll ] } bind def % \end{macrocode} @@ -1885,7 +1863,7 @@ tx@IntersectDict begin % \begin{macrocode} /IntersectBeziers { 2 copy length 2 eq exch length 2 eq and { - IntersectLines + IntersectLineSegms }{ 2 copy [0 1] [0 1] IterateIntersection } ifelse @@ -1895,10 +1873,10 @@ tx@IntersectDict begin % \end{macro} % % \begin{macro}{IntersectLines} -% +% Intersect two lines. % \begin{pssyntax} % \PSarray{lineA} \PSarray{lineB} \PSop{IntersectLines} -% \PSarray{lineA} \PSarray{tA} \PSarray{lineB} \PSarray{tB} +% \PSarray{lineA} \PSarray{lineB} \PSarray{tA} \PSarray{tB} % \end{pssyntax} % \begin{macrocode} /IntersectLines { @@ -1908,26 +1886,162 @@ tx@IntersectDict begin 8 -2 roll 2 copy 10 4 roll 4 2 roll 2 copy 6 2 roll 10 2 roll VecSub 6 2 roll 4 2 roll VecSub - 8 4 roll 4 2 roll VecSub % X3-X4 Y3-Y4 X2-X1 Y2-Y1 X3-X1 Y3-Y1 % b1 b2 a1 a2 c1 c2 + 8 4 roll 4 2 roll VecSub +% \end{macrocode} +% X3-X4 Y3-Y4 X2-X1 Y2-Y1 X3-X1 Y3-Y1 % b1 b2 a1 a2 c1 c2 +% \begin{macrocode} 6 copy 12 -4 roll neg 4 -1 roll mul 3 1 roll mul add dup 0 eq { - % no intersections +% \end{macrocode} +% no intersections +% \begin{macrocode} 9 { pop } repeat [] [] } { dup 10 1 roll 5 1 roll 4 -1 roll mul 3 1 roll mul sub exch div - 6 1 roll 4 -1 roll mul 3 1 roll mul sub exch div - 2 copy 2 copy 0 ge exch 0 ge and 3 1 roll 1 le exch 1 le and and { - [ exch ] exch [ exch ] - } { - pop pop [] [] - } ifelse - } ifelse + 6 1 roll 4 -1 roll mul 3 1 roll mul sub exch div + [ exch ] exch [ exch ] + } ifelse + DebugEnd +} bind def +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{IntersectLineSegms} +% Intersect two line segments. This uses the output of +% \PSop{IntersectLines} and checks if both line parameters are in the +% range [0,1]. +% \begin{pssyntax} +% \PSarray{lineA} \PSarray{lineB} \PSop{IntersectLineSegms} +% \PSarray{lineA} \PSarray{lineB} \PSarray{tA} \PSarray{tB} +% \end{pssyntax} +% \begin{macrocode} +/IntersectLineSegms { + IntersectLines + dup length 0 eq not { +% \end{macrocode} +% IntersectLines has found an intersection +% \begin{macrocode} + 0 get exch 0 get + 2 copy 2 copy 0 ge exch 0 ge and 3 1 roll 1 le exch 1 le and and { + [ exch ] exch [ exch ] + } { + pop pop [] [] + } ifelse + } if +} bind def +% \end{macrocode} +% \end{macro} +% \begin{macro}{IntersectLineSegmLine} +% Intersect a line segment with a line. This uses +% \PSop{IntersectLines} and checks if the line parameter of the line +% segment is in the range [0,1]. +% \begin{pssyntax} +% \PSarray{lineA} \PSarray{lineSegmB} \PSop{IntersectLineLineSegm} +% \PSarray{lineA} \PSarray{tA} \PSarray{lineSegmB} \PSarray{tB} +% \end{pssyntax} +% \begin{macrocode} +/IntersectLineLineSegm { + tx@IntersectDict begin IntersectLines end + dup length 0 eq not { +% \end{macrocode} +% IntersectLines has found an intersection +% \begin{macrocode} + 0 get dup dup 0 ge exch 1 le and { + [ exch ] + } { + pop pop [] [] + } ifelse + } if + 3 -1 roll exch +} bind def +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{IntersectLinePath} +% Compute the first intersection of a line with a path. If an intersection was +% found, also the respective path segment remains on the stack for +% later computations. +% \begin{pssyntax} +% \PSarray{lineA} \PSarray{pathB} \PSop{IntersectLinePath} +% \PSarray{segment} \PSvar{t} \PSarray{intersection} +% \end{pssyntax} +% \begin{macrocode} +/IntersectLinePath { + (IntersectLinePath) DebugBegin + 3 dict begin + PreparePath +% \end{macrocode} +% First elongate lineA such, that it could intersect with any segment in pathB +% \begin{macrocode} + 2 copy ElongateLine exch 3 -1 roll pop + /isect [] def + /t -1 def + /n -1 def + { + /n n 1 add def + 2 copy IntersectBeziers + dup 5 1 roll LoadIntersectionPoints + dup length 0 gt { +% \end{macrocode} +% one intersection found, clean up and exit +% \begin{macrocode} + /isect exch def + 0 get aload pop add 0.5 mul n add /t exch def + exch pop + exit + } { + pop pop pop + } ifelse + } forall + t isect + end DebugEnd } bind def % \end{macrocode} % \end{macro} +% +% \begin{macro}{ElongateLine} +% Elongate \PSarray{line} to potentially intersect with every segment +% in \PSarray{path}. +% \begin{pssyntax} +% \PSarray{lineA} \PSarray{path} \PSop{ElongateLine} \PSarray{lineA'} +% \end{pssyntax} +% \begin{macrocode} +/ElongateLine { + exch { aload pop } forall + 4 2 roll 2 copy 6 2 roll + VecSub 0 5 1 roll + 6 -1 roll { +% \end{macrocode} +% 0 x0 y0 dx dy [segm\_i] +% \begin{macrocode} + { + aload pop +% \end{macrocode} +% max x0 y0 dx dy P\_ij.x P\_ij.y +% \begin{macrocode} + 6 2 roll 4 copy 10 4 roll + 6 2 roll VecSub 4 2 roll + tx@EcldDict begin Project end + tx@Dict begin Pyth end + 6 -1 roll 2 copy + gt { pop } { exch pop } ifelse + 5 1 roll + } forall + } forall +% \end{macrocode} +% dmax x0 y0 dx dy +% \begin{macrocode} + % for a line + 5 -1 roll VecScale 4 copy VecSub ToPnt 5 1 roll VecAdd ToPnt ToPnt + % for a ray + %4 2 roll 2 copy ToPnt 6 1 roll 4 2 roll 5 -1 roll 1.1 mul VecScale VecAdd ToPnt ToPnt +} bind def +% \end{macrocode} +% \end{macro} +% % \begin{macro}{IntersectPaths} % \begin{pssyntax} % \PSarray{pathA} \PSarray{pathB} \PSop{IntersectPaths} @@ -1959,7 +2073,6 @@ tx@IntersectDict begin } forall pop % remove [pathA] [ isect { aload pop } forall ] 3 1 roll tA exch tB - % [intersections] [pathA] [tA] [pathB] [tB] end DebugEnd } bind def @@ -1978,19 +2091,18 @@ tx@IntersectDict begin 2 copy PreparePath dup length /n exch def /isect [] def /tA [] def /tB [] def - { % [curveA] [Bi] + { /n n 1 sub def - exch dup 3 -1 roll % [curveA] [curveA] [Bi] + exch dup 3 -1 roll IntersectBeziers - 4 copy LoadIntersectionPoints % [curveA] [tA] [curveB] [tB] + 4 copy LoadIntersectionPoints [ exch isect aload pop ] /isect exch def pop 3 -1 roll pop [ tB aload length 2 add -1 roll TArray { n add } forall ] /tB exch def [ tA aload length 2 add -1 roll TArray aload pop ] /tA exch def } forall - pop % remove [curveA] + pop [ isect { aload pop } forall ] 3 1 roll tA exch tB - % [intersections] [curveA] [tA] [pathB] [tB] end DebugEnd } bind def @@ -2000,23 +2112,71 @@ tx@IntersectDict begin % \end{macrocode} % \end{macro} % +% \begin{macro}{MergeAndSort} +% Merge and sort two arrays. That may be point arrays or simple +% arrays. Both arrays must be of the same type, but that is not +% checked. +% \begin{macrocode} +/MergeAndSortArrays { + [ 3 1 roll aload pop counttomark -1 roll aload pop ] + dup length 0 gt { + dup dup 0 get type /arraytype eq { + hulldict /comp get + } { + /lt + } ifelse + exch quicksort + } if +} bind def +% \end{macrocode} +% \end{macro} +% % \begin{macro}{SaveIntersection} % \begin{pssyntax} -% \PSname{isectname} \PSname{nameA} \PSname{nameB} % \PSarray{intersectionpoints} \PSarray{A} \PSarray{tA} \PSarray{B} \PSarray{tB} +% \PSname{nameA} \PSname{nameB} \PSname{isectname} \PSvar{add?} % \PSop{SaveIntersection} % \end{pssyntax} % \begin{macrocode} /SaveIntersection { (SaveIntersection) DebugBegin - 4 dict dup 10 -1 roll exch def - begin % - /Points 6 -1 roll def - 5 -1 roll dup 4 -1 roll def % /curveA [curveA] [tA] [tB] /curveB /curveB [curveB] def - nametostr (@t) strcat cvn exch TArray def % /curveA [curveA] [tA] /curveB@t [tB] def - 3 -1 roll dup 4 -1 roll def - nametostr (@t) strcat cvn exch TArray def - end + exch dup 3 1 roll % isectname add? isectname + currentdict exch known and { +% \end{macrocode} +% Want to add the new intersections to an existing intersection. Merge +% the new arrays with the existing ones and resort the \PSvar{Points} +% and \PSvar{\ldots @t} arrays. +% \begin{macrocode} + load begin % pnts A tA B tB /A /B + dup currentdict exch known { % /nameB already saved. + 4 -1 roll pop % pnts A tA tB /A /B + nametostr (@t) strcat cvn dup load 4 -1 roll + MergeAndSortArrays def + } { + dup 5 -1 roll def % pnts A tA B tB /A /B + nametostr (@t) strcat cvn 3 -1 roll TArray def + } ifelse % pnts A tA /A + dup currentdict exch known { % /nameB already saved. + 3 -1 roll pop + nametostr (@t) strcat cvn dup load 3 -1 roll + MergeAndSortArrays def + } { + dup 4 -1 roll def + nametostr (@t) strcat cvn exch TArray def + } ifelse + /Points exch ArrayToPointArray Points ArrayToPointArray + MergeAndSortArrays PointArrayToArray def + end + } { + 4 dict dup 3 1 roll def + begin + dup 5 -1 roll def + nametostr (@t) strcat cvn 3 -1 roll TArray def + dup 4 -1 roll def + nametostr (@t) strcat cvn exch TArray def + /Points exch def + end + } ifelse DebugEnd } bind def % \end{macrocode} @@ -2034,7 +2194,6 @@ tx@IntersectDict begin % \end{pssyntax} % \begin{macrocode} /TArray { - (TArray) DebugBegin dup length 0 gt { dup 0 get type /arraytype eq { [ exch @@ -2044,7 +2203,6 @@ tx@IntersectDict begin } if dup /lt exch quicksort } if - DebugEnd %1 debug } bind def % \end{macrocode} % \end{macro} @@ -2059,41 +2217,113 @@ tx@IntersectDict begin /linetype /lineto load def /curvetype /curveto load def } bind def -InitTracing +%^^AInitTracing /GetFullPath { + (GetFullPath) DebugBegin { /movetype counttomark 3 roll } { /linetype counttomark 3 roll } { /curvetype counttomark 7 roll }{} pathforall + DebugEnd +} bind def +% \end{macrocode} +% +% \begin{macro}{ReversePath} +% \begin{macrocode} +/ReversePath { + gsave newpath + [ exch aload pop InitTracing + { counttomark 0 eq { exit } if + load exec + } loop + reversepath + GetFullPath ] + grestore } bind def % \end{macrocode} +% \end{macro} +% +% \begin{macro}{ReverseCurve} +% Reverse direction of a bezier curve. +% \begin{pssyntax} +% \PSarray{\PSarray{X0 Y0} \ldots \PSarray{XN YN}} +% \PSop{ReverseCurve} \PSarray{\PSarray{XN YN} \ldots \PSarray{X0 Y0}} +% \end{pssyntax} +% \begin{macrocode} +/ReverseCurve { + PointArrayToArray aload pop % [ tstart tstop [ X0 Y0 X1 Y1... + counttomark -2 4 { 2 roll } for ] ArrayToPointArray +} bind def +% \end{macrocode} +% \end{macro} % +% \begin{macro}{ReverseInterval} +% \begin{pssyntax} +% \PSarray{path} \PSvar{tstart} \PSvar{tstop} \PSop{ReverseInterval} +% \PSarray{path} \PSvar{L-tstop} \PSvar{L-tstart} +% \end{pssyntax} +% \begin{macrocode} +/ReverseInterval { + 3 -1 roll dup 4 1 roll GetSegmentCount + dup 4 1 roll exch sub 3 1 roll sub exch +} bind def +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{UnifyInterval} +% Unifies the interval \PSarray{tstart tstop}. If \PSvar{tstart} is +% negative, 0 is used. If \PSvar{tstop} is negative, the curve length +% is used. A too large \PSvar{tstop} is also truncated to the curve +% length. +% \begin{pssyntax} +% \PSarray{curve} \PSvar{tstart tstop} \PSop{UnifyInterval} +% \PSarray{curve} \PSvar{tstart' tstop} +% \end{pssyntax} +% \begin{macrocode} +/UnifyInterval { + exch dup 0 lt { pop 0 } if exch + 3 -1 roll dup 4 1 roll GetSegmentCount + 2 copy exch dup 3 1 roll % [curve] tstart tstop cnt tstop cnt tstop + lt exch 0 lt or { exch } if pop % (tstop < 0 | cnt < tstop) +} bind def +% \end{macrocode} +% \end{macro} % \begin{macro}{PreparePath} % [ ... /movetype ... /linetype .../curvetype ] % \begin{macrocode} /PreparePath { + (PreparePath) DebugBegin [ exch aload pop { dup type /nametype eq not { exit } if dup /movetype eq { - pop ToVec /@mycp exch def + pop ToPnt /@mycp exch def } { dup /linetype eq { - pop [ @mycp 4 2 roll 2 copy ToVec /@mycp exch def ToVec ] + pop [ @mycp 4 2 roll 2 copy ToPnt /@mycp exch def ToPnt ] } { - pop [ @mycp 8 2 roll 2 copy ToVec /@mycp exch def - ToVec 5 1 roll ToVec 4 1 roll ToVec 3 1 roll ] + pop [ @mycp 8 2 roll 2 copy ToPnt /@mycp exch def + ToPnt 5 1 roll ToPnt 4 1 roll ToPnt 3 1 roll ] } ifelse counttomark 1 roll } ifelse } loop ] + DebugEnd } bind def % \end{macrocode} % \end{macro} % % \begin{macro}{GetSegmentCount} -% \PSarray{CurveOrPath} \PSop{GetSegmentCount} -> number of /linetype and /curvetypes +% Count the number of path or bezier curve segments. Bezier curves +% always have the length 1, independent of their order. For paths, +% only the \PSname{linetype} and \PSname{curvetype} segments are +% counted. +% \begin{pssyntax} +% \PSarray{CurveOrPath} \PSop{GetSegmentCount} \PSvar{cnt} +% \end{pssyntax} +% % \begin{macrocode} /GetSegmentCount { + (GetSegmentCount) DebugBegin dup IsPath { [ exch aload pop 0 { @@ -2112,14 +2342,14 @@ InitTracing exch pop } { % a Bezier curve is a single segment - pop 1 + length 0 gt { 1 } { 0 } ifelse } ifelse + DebugEnd } bind def % \end{macrocode} % \end{macro} % % \begin{macro}{LoadLineIntersectionPoints} -% Prepare \PSarray{Curve} for use with tx@Func % \begin{pssyntax} % \PSarray{curve} \PSarray{t} \PSop{LoadLineIntersectionPoints} % \PSarray{I0.x I0.y \ldots IN.x YN.x} @@ -2153,7 +2383,9 @@ InitTracing [ exch { aload pop } forall ] exch [ exch { aload pop } forall ] } repeat - % [A0.x A0.y ... AM.x AM.y] [tA0a tA0b ... tAMa tAMb] [tB0a tB0b ... tBNa tBNb] [B0.x B0.y ... BN.x BN.y] +% \end{macrocode} +% [A0.x A0.y ... AM.x AM.y] [tA0a tA0b ... tAMa tAMb] [tB0a tB0b ... tBNa tBNb] [B0.x B0.y ... BN.x BN.y] +% \begin{macrocode} tx@Dict begin tx@FuncDict begin 2 dict begin dup length 2 idiv 1 sub /BezierType exch def /Points exch def [ exch { GetBezierCoor } forall ] @@ -2161,15 +2393,18 @@ InitTracing dup length 2 idiv 1 sub /BezierType exch def /Points exch def [ exch { GetBezierCoor } forall ] end - %2 debug - % [IB0.xa IB0.ya IB0.xb IB0.yb ... IBM.yb] [IA0.xa IA0.ya IA0.xb IA0.yb ... IAM.yb] +% \end{macrocode} +% [IB0.xa IB0.ya IB0.xb IB0.yb ... IBM.yb] [IA0.xa IA0.ya IA0.xb IA0.yb ... IAM.yb] +% \begin{macrocode} 2 { [ exch aload length 4 idiv { [ 5 1 roll ] counttomark 1 roll } repeat ] exch } repeat - % [[IB0.xa ...] ... [... IBM.yb]] [[IA0.xa IA0.ya IA0.xb IA0.yb] ...[IAM.xa ... IAM.yb]] +% \end{macrocode} +% [[IB0.xa ...] ... [... IBM.yb]] [[IA0.xa IA0.ya IA0.xb IA0.yb] ...[IAM.xa ... IAM.yb]] +% \begin{macrocode} 2 { dup hulldict /comp get exch quicksort exch } repeat @@ -2180,16 +2415,7 @@ InitTracing 2 copy aload pop VecSub Pyth exch aload pop VecSub Pyth lt { exch } if pop aload pop VecAdd 0.5 VecScale - } for - % merge near intersection points - %counttomark 2 idiv 1 1 3 -1 roll { - % pop - % counttomark 4 lt { exit } if - % 4 copy 4 2 roll ToVec 3 1 roll ToVec AreNear { - - % } - %} for - ] + } for ] end end end DebugEnd @@ -2245,6 +2471,11 @@ InitTracing } if DebugEnd } bind def +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{TArraysRemoveDup} +% \begin{macrocode} /TArraysRemoveDup { 4 dict begin /tB exch def @@ -2286,14 +2517,13 @@ InitTracing /depth depth 1 add def /dom null def /counter counter 1 add def - CheckIT { (>> curve subdivision performed: dom(A) = ) domA CurveToString strcat (, dom(B) = ) strcat domB CurveToString strcat ( <<) strcat == } if CurveA IsConstant CurveB IsConstant and { - CurveA MiddlePoint ToVec - CurveB MiddlePoint ToVec AreNear { + CurveA MiddlePoint ToPnt + CurveB MiddlePoint ToPnt AreNear { domA domB 4 -1 roll exch PutInterval PutInterval } { pop pop @@ -2311,8 +2541,8 @@ InitTracing iter 100 ge { false } { - CurveA MiddlePoint ToVec - CurveB MiddlePoint ToVec AreNear { + CurveA MiddlePoint ToPnt + CurveB MiddlePoint ToPnt AreNear { domA domB true }{ false @@ -2328,7 +2558,6 @@ InitTracing (, iter: ) iter 20 string cvs strcat strcat (, depth: ) depth 20 string cvs strcat strcat == } if - CurveA CurveB ClipCurve /dom exch def CheckIT {(dom : ) dom CurveToString strcat == } if @@ -2355,8 +2584,8 @@ InitTracing (C1: [ ) CurveA { CurveToString ( ) strcat strcat } forall (]) strcat == (C2: [ ) CurveB { CurveToString ( ) strcat strcat } forall (]) strcat == } if - CurveA MiddlePoint ToVec - CurveB MiddlePoint ToVec AreNear { + CurveA MiddlePoint ToPnt + CurveB MiddlePoint ToPnt AreNear { domA domB true } { false @@ -2492,7 +2721,7 @@ InitTracing ToUnitRange exch ToUnitRange 2 copy gt { exch } if - ToVec + ToPnt } bind def % \end{macrocode} % \end{macro} @@ -2532,7 +2761,7 @@ InitTracing % \end{pssyntax} % \begin{macrocode} /CloneVec { - aload pop ToVec + aload pop ToPnt } bind def % \end{macrocode} % \end{macro} @@ -2648,7 +2877,7 @@ InitTracing 3 -1 roll dup 1 exch sub 3 1 roll % [A] (1-t) [B] t exch aload pop 3 -1 roll VecScale % [A] (1-t) B.x*t B.y*t 4 2 roll - exch aload pop 3 -1 roll VecScale VecAdd ToVec % [A.x*(1-t)+B.x*t A.y*(1-t)+B.y*t] + exch aload pop 3 -1 roll VecScale VecAdd ToPnt % [A.x*(1-t)+B.x*t A.y*(1-t)+B.y*t] DebugEnd } bind def % \end{macrocode} @@ -3048,25 +3277,26 @@ InitTracing % \end{pssyntax} % \begin{macrocode} /ShowPathPortion { - 6 dict begin + (ShowPathPortion) DebugBegin + 8 dict begin /tstop exch def /tstart exch def + /savecp { ToPnt cvx /@cp exch def } def InitTracing /n 0 def mark exch aload pop - { - counttomark 0 eq n tstop ge or { pop exit } if + { + counttomark 0 eq n tstop ge or { cleartomark exit } if dup /movetype eq not { /n n 1 add def } if - dup /movetype eq { - load exec + pop savecp } { - tstart n gt { + tstart n ge { % \end{macrocode} % current path section is before tstop % \begin{macrocode} /curvetype eq { 6 2 roll 4 { pop } repeat } if - movetype + savecp } { tstart n 1 sub gt tstop n lt or { % \end{macrocode} @@ -3075,7 +3305,8 @@ InitTracing tstart n sub 1 add tstop n sub 1 add ToUnitInterval exch /linetype eq { - 3 1 roll ToVec currentpoint ToVec exch ToVec + 3 1 roll ToPnt + tstart n 1 sub gt { @cp ToPnt } { currentpoint ToPnt } ifelse exch ToPnt dup 3 -1 roll Portion aload pop exch tstart n 1 sub gt { @@ -3087,33 +3318,33 @@ InitTracing % \end{macrocode} % only a single segment, draw also the ending arrow % \begin{macrocode} - currentpoint 4 2 roll ArrowB lineto pop pop + currentpoint 4 2 roll ArrowB linetype pop pop } { % \end{macrocode} % other segments to follow % \begin{macrocode} - lineto + linetype } ifelse } { % \end{macrocode} % this is the last segment % \begin{macrocode} - pop aload pop currentpoint 4 2 roll ArrowB lineto pop pop + pop aload pop currentpoint 4 2 roll ArrowB linetype pop pop } ifelse } { - 7 1 roll [ currentpoint 9 3 roll ] ArrayToPointArray - dup 3 -1 roll Portion + 7 1 roll + [ tstart n 1 sub gt { @cp }{ currentpoint } ifelse + 9 3 roll ] ArrayToPointArray + dup 3 -1 roll + Portion { aload pop } forall - 8 -2 roll - tstart n 1 sub gt { moveto } { pop pop } ifelse - 6 -2 roll currentpoint ArrowA 6 2 roll - tstop n le { -% \end{macrocode} -% only a single segment -% \begin{macrocode} - ArrowB - } if - curveto + tstart n 1 sub gt { + 8 -4 roll 4 2 roll ArrowA 6 2 roll + } { + 8 -2 roll pop pop + } ifelse + tstop n le { ArrowB } if + curvetype } ifelse }{ % \end{macrocode} @@ -3124,27 +3355,27 @@ InitTracing % the first segment % \begin{macrocode} /linetype eq { - currentpoint ArrowA + @cp ArrowA tstop n eq { % \end{macrocode} % a single, full segment % \begin{macrocode} - currentpoint 4 2 roll ArrowB lineto pop pop + currentpoint 4 2 roll ArrowB linetype pop pop } { % \end{macrocode} % not the last segment % \begin{macrocode} - lineto + linetype } ifelse } { - 6 -2 roll currentpoint ArrowA 6 2 roll + 6 -2 roll @cp ArrowA 6 2 roll tstop n eq { % \end{macrocode} % single, full curve segment % \begin{macrocode} ArrowB } if - curveto + curvetype } ifelse } { % \end{macrocode} @@ -3155,12 +3386,12 @@ InitTracing % \end{macrocode} % last segment but not a single one % \begin{macrocode} - currentpoint 4 2 roll ArrowB lineto pop pop + currentpoint 4 2 roll ArrowB linetype pop pop }{ % \end{macrocode} % full middle segment % \begin{macrocode} - lineto + linetype } ifelse } { tstop n eq { @@ -3169,7 +3400,7 @@ InitTracing % \begin{macrocode} ArrowB } if - curveto + curvetype } ifelse } ifelse } ifelse @@ -3177,6 +3408,113 @@ InitTracing } ifelse } loop end + DebugEnd +} bind def +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{GetCurvePoint} +% Get the coordinates of the curve point at \PSvar{t}. +% \begin{pssyntax} +% \PSvar{t} \PSarray{curve} \PSop{GetCurvePoint} \PSvar{X Y} +% \end{pssyntax} +% \begin{macrocode} +/GetCurvePoint { + dup IsPath { + 5 dict begin + exch dup /tstart exch def + 1 add cvi /tstop exch def + /savecp { ToPnt cvx /@cp exch def } def + /n 0 def + mark exch aload pop + { + counttomark 0 eq n tstop ge or { cleartomark exit } if + dup /movetype eq not { /n n 1 add def } if + dup /movetype eq { + pop savecp + } { + tstart n ge { +% \end{macrocode} +% current path section is before tstop +% \begin{macrocode} + /curvetype eq { 6 2 roll 4 { pop } repeat } if + savecp + } { + tstart n 1 sub gt { + tstart n sub 1 add tstop n sub 1 add + ToUnitInterval exch + /linetype eq { + 3 1 roll ToPnt + tstart n 1 sub gt { @cp ToPnt } { currentpoint ToPnt } ifelse exch ToPnt + dup 3 -1 roll Portion + } { + 7 1 roll + [ @cp 9 3 roll ] ArrayToPointArray + dup 3 -1 roll + Portion + } ifelse + 0 get aload pop + }{ +% \end{macrocode} +% full segment +% \begin{macrocode} + /curvetype eq { + pop pop pop pop + } if + } ifelse + counttomark 1 add 2 roll cleartomark exit + } ifelse + } ifelse + } loop + end + } { + exch dup 0 eq { + pop 0 get aload pop + } { + 0 exch ToUnitInterval exch dup 3 -1 roll Portion + dup length 1 sub get aload pop + } ifelse + } ifelse +} bind def +% \end{macrocode} +% \end{macro} +% \begin{macro}{TraceCurveOrPath} +% \begin{pssyntax} +% \PSarray{curve} \PSvar{tstart tstop} \PSproc{drawcurve} +% \PSop{TraceCurveOrPath} +% \end{pssyntax} +% \begin{macrocode} +/TraceCurveOrPath { + 4 1 roll + UnifyInterval + 3 -1 roll dup IsPath { + 4 -1 roll pop + 3 1 roll 2 copy gt { +% \end{macrocode} +% reverse the path, draw everything and resave the path +% \begin{macrocode} + ReverseInterval + 3 -1 roll ReversePath 3 1 roll + } if + ShowPathPortion + }{ % tstart tstop [curve] + mark exch 4 2 roll % [ [curve] tstart tstop + 2 copy gt { % tstart > tstop +% \end{macrocode} +% Exchange tstart and tstop and reverse the curve array +% \begin{macrocode} + exch + [ 4 -1 roll ReverseCurve 3 1 roll % [ [curve'] tstart tstop + } if + ToUnitInterval exch dup 3 -1 roll Portion + { aload pop } forall +% \end{macrocode} +% reverse the point order +% \begin{macrocode} + counttomark -2 4 { 2 roll } for + counttomark 2 sub 2 idiv + counttomark 2 add -1 roll exec + } ifelse } bind def % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/pst-intersect/pst-intersect.ins b/Master/texmf-dist/source/latex/pst-intersect/pst-intersect.ins index 23ad7bb389f..5fb106ed5f6 100644 --- a/Master/texmf-dist/source/latex/pst-intersect/pst-intersect.ins +++ b/Master/texmf-dist/source/latex/pst-intersect/pst-intersect.ins @@ -48,7 +48,7 @@ This is a generated file. Project: pst-intersect -Version: 0.3 (2014/03/04) +Version: 0.4 (2014/03/16) Copyright (C) 2007-2014 by Christoph Bersch diff --git a/Master/texmf-dist/tex/generic/pst-intersect/pst-intersect.tex b/Master/texmf-dist/tex/generic/pst-intersect/pst-intersect.tex index 099d487e748..7561f8c00c9 100644 --- a/Master/texmf-dist/tex/generic/pst-intersect/pst-intersect.tex +++ b/Master/texmf-dist/tex/generic/pst-intersect/pst-intersect.tex @@ -9,7 +9,7 @@ %% This is a generated file. %% %% Project: pst-intersect -%% Version: 0.3 (2014/03/04) +%% Version: 0.4 (2014/03/16) %% %% Copyright (C) 2007-2014 by Christoph Bersch %% @@ -62,6 +62,8 @@ }% \newif\PIT@saveintersections \define@boolkey[psset]{intersect}[PIT@]{saveintersections}[true]{} +\newif\PIT@addintersections +\define@boolkey[psset]{intersect}[PIT@]{addintersections}[true]{} \psset[intersect]{% tstart=-1, @@ -69,7 +71,8 @@ istart=-1, istop=-1, name={}, - saveintersections + saveintersections, + addintersections=false }% \def\PIT@use@pscode{% \pstverb{% @@ -145,45 +148,18 @@ \PIT@checkname{#1}% \addto@pscode{% \pst@intersectdict - \PIT@key@tstop\space dup 0 lt { pop \PIT@name{#1} GetSegmentCount } if - \PIT@key@tstart\space dup 0 lt { pop 0 } if exch - \PIT@name{#1} GetSegmentCount - 2 copy exch dup 3 1 roll - lt exch 0 lt or { exch } if pop - \PIT@name{#1} dup IsPath { - 3 1 roll 2 copy gt { - exch 3 -1 roll dup 4 1 roll GetSegmentCount - dup 4 1 roll exch sub 3 1 roll sub exch - gsave newpath - [ 4 -1 roll aload pop InitTracing - { counttomark 0 eq { exit } if - load exec - } loop - reversepath - GetFullPath ] 3 1 roll - grestore - } if - ShowPathPortion - }{ - [ exch dup 5 -2 roll - 2 copy gt { - exch - 2 copy gt { exch } if - [ 5 -2 roll pop PointArrayToArray aload pop - counttomark -2 4 { 2 roll } for ] ArrayToPointArray dup - 4 2 roll - } if - ToUnitInterval Portion - { aload pop } forall - counttomark -2 4 { 2 roll } for - counttomark 2 sub 2 idiv - \psk@plotpoints - exch + /\PIT@name{#1} currentdict exch known not { + (You haven't defined the curve '#1') == + } if + \PIT@name{#1} \PIT@key@tstart\space\PIT@key@tstop\space % [curve] tstart tstop + {\psk@plotpoints exch \txFunc@BezierCurve \ifshowpoints \txFunc@BezierShowPoints \else pop \fi - } ifelse + } + TraceCurveOrPath end }% + %\showpointsfalse \end@OpenObj }% \def\PIT@traceintersection#1#2{% @@ -213,53 +189,20 @@ } { \PIT@key@tstart } ifelse - dup 0 lt { pop 0 } if exch % [curve] t_istart|tstart [ts] - % dup length \PIT@key@istop\space ge 0 \PIT@key@istop\space lt and { \PIT@key@istop\space cvi 1 sub get } { pop \PIT@key@tstop - } ifelse - 3 -1 roll dup 4 1 roll GetSegmentCount - 2 copy exch dup 3 1 roll % [curve] tstart tstop cnt tstop cnt tstop - lt exch 0 lt or { exch } if pop % (tstop < 0 | cnt < tstop) - 3 -1 roll dup - IsPath { - 3 1 roll - 2 copy gt { - exch 3 -1 roll dup 4 1 roll GetSegmentCount - dup 4 1 roll exch sub 3 1 roll sub exch - gsave newpath - [ 4 -1 roll aload pop InitTracing - { counttomark 0 eq { exit } if - load exec - } loop - reversepath - GetFullPath ] 3 1 roll - grestore - } if - ShowPathPortion - }{ - [ exch dup 5 -2 roll - exch dup 0 lt { pop 0 } if exch - dup 0 lt { pop 1 } if - 2 copy gt { - exch - [ 5 -2 roll pop PointArrayToArray aload pop - counttomark -2 4 { 2 roll } for ] ArrayToPointArray dup - 4 2 roll - } if - ToUnitInterval Portion - { aload pop } forall - counttomark 2 sub 2 idiv - \psk@plotpoints - exch + } ifelse % [curve] tstart tstop + {\psk@plotpoints exch \txFunc@BezierCurve \ifshowpoints \txFunc@BezierShowPoints \else pop \fi - } ifelse + } + TraceCurveOrPath end }% + %\showpointsfalse \end@OpenObj }% \def\psintersect{\pst@object{psintersect}} @@ -295,7 +238,8 @@ 4 copy LoadIntersectionPoints 5 1 roll } ifelse } ifelse - /\PIT@@name\space /\PIT@name{#1} /\PIT@name{#2} 8 3 roll + /\PIT@name{#1} /\PIT@name{#2} /\PIT@@name + \ifPIT@addintersections true \else false \fi SaveIntersection }% \ifPIT@saveintersections @@ -356,6 +300,15 @@ end \tx@UserCoor /I-#1#3.y exch def /I-#1#3.x exch def }% +\def\psGetCurvePoint#1#2{% + \pst@intersectdict + currentdict /\PIT@name{#1} known not { + (You haven't defined the curve or path '#1') == + } if + #2 \PIT@name{#1} GetCurvePoint \tx@UserCoor + end + /I-#1.y exch def /I-#1.x exch def +}% \catcode`\@=\PstAtCode\relax \endinput %% diff --git a/Master/texmf-dist/tex/latex/pst-intersect/pst-intersect.sty b/Master/texmf-dist/tex/latex/pst-intersect/pst-intersect.sty index 05d22fe10b8..7743ac6e046 100644 --- a/Master/texmf-dist/tex/latex/pst-intersect/pst-intersect.sty +++ b/Master/texmf-dist/tex/latex/pst-intersect/pst-intersect.sty @@ -9,7 +9,7 @@ %% This is a generated file. %% %% Project: pst-intersect -%% Version: 0.3 (2014/03/04) +%% Version: 0.4 (2014/03/16) %% %% Copyright (C) 2007-2014 by Christoph Bersch %% @@ -31,7 +31,7 @@ %% \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{pst-intersect} - [2014/03/04 v0.3 package wrapper for pst-intersect.tex] + [2014/03/16 v0.4 package wrapper for pst-intersect.tex] \RequirePackage{pstricks} \RequirePackage{pst-xkey} \RequirePackage{pst-node} @@ -39,7 +39,7 @@ \input{pst-intersect.tex} \IfFileExists{pst-intersect.pro}{% \ProvidesFile{pst-intersect.pro} - [2014/03/04 PostScript prologue file] + [2014/03/16 PostScript prologue file] \@addtofilelist{pst-intersect.pro}}{}% \endinput %% -- cgit v1.2.3