From e767448d0591f5dbb0cd485e4b014becdcbd1ba4 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 28 May 2009 23:56:03 +0000 Subject: asymptote 1.74 git-svn-id: svn://tug.org/texlive/trunk@13514 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/utils/asymptote/base/bezulate.asy | 8 +- Build/source/utils/asymptote/base/embed.asy | 6 +- Build/source/utils/asymptote/base/plain_Label.asy | 2 +- Build/source/utils/asymptote/base/plain_pens.asy | 20 ++++- .../source/utils/asymptote/base/plain_strings.asy | 31 ++++--- Build/source/utils/asymptote/base/three.asy | 54 ++++++++++--- .../source/utils/asymptote/base/three_surface.asy | 94 +++++++++++++--------- Build/source/utils/asymptote/base/version.asy | 2 +- 8 files changed, 146 insertions(+), 71 deletions(-) (limited to 'Build/source/utils/asymptote/base') diff --git a/Build/source/utils/asymptote/base/bezulate.asy b/Build/source/utils/asymptote/base/bezulate.asy index c47f3144912..2710996b322 100644 --- a/Build/source/utils/asymptote/base/bezulate.asy +++ b/Build/source/utils/asymptote/base/bezulate.asy @@ -1,6 +1,7 @@ // Bezier triangulation routines written by Orest Shardt, 2008. -private real fuzz = sqrtEpsilon; +private real fuzz=sqrtEpsilon; +real duplicateFuzz=1e-3; // Work around font errors. int countIntersections(path[] p, pair start, pair end) { @@ -46,7 +47,7 @@ path[][] containmentTree(path[] paths) bool isDuplicate(pair a, pair b, real relSize) { - return abs(a-b) <= sqrtEpsilon*relSize; + return abs(a-b) <= duplicateFuzz*relSize; } path removeDuplicates(path p) @@ -101,8 +102,7 @@ void connect(path[] paths, path[] result, path[] patch) // find first intersection of line segment with outer curve path line = start--start+d*direction; real[][] ints=intersections(line,outer,fuzz); - assert(ints.length != 0); - real endtime=ints[0][1]; // endtime is time on outer + real endtime=ints.length > 0 ? ints[0][1] : 0; // endtime is time on outer pair end = point(outer,endtime); line = start--end; path rline = reverse(line); diff --git a/Build/source/utils/asymptote/base/embed.asy b/Build/source/utils/asymptote/base/embed.asy index 3fe3d38720c..5695eadab56 100644 --- a/Build/source/utils/asymptote/base/embed.asy +++ b/Build/source/utils/asymptote/base/embed.asy @@ -1,11 +1,13 @@ -texpreamble(" +if(latex()) { + texpreamble(" \ifx\pdfhorigin\undefined% \usepackage[3D,dvipdfmx]{movie15} \else% \usepackage[3D]{movie15} \fi% "); -usepackage("hyperref","setpagesize=false,unicode"); + usepackage("hyperref","setpagesize=false,unicode"); +} // See http://www.ctan.org/tex-archive/macros/latex/contrib/movie15/README // for documentation of the options. diff --git a/Build/source/utils/asymptote/base/plain_Label.asy b/Build/source/utils/asymptote/base/plain_Label.asy index 77a04deb007..1279880ca3a 100644 --- a/Build/source/utils/asymptote/base/plain_Label.asy +++ b/Build/source/utils/asymptote/base/plain_Label.asy @@ -172,7 +172,7 @@ side operator * (real x, side s) align operator cast(pair dir) {align A; A.init(dir,false); return A;} align operator cast(triple dir) {align A; A.init(dir,false); return A;} align operator cast(side side) {align A; A.init(side.align,true); return A;} -align NoAlign; +restricted align NoAlign; void write(file file=stdout, align align, suffix suffix=endl) { diff --git a/Build/source/utils/asymptote/base/plain_pens.asy b/Build/source/utils/asymptote/base/plain_pens.asy index 88fc112f684..5dba51dbda4 100644 --- a/Build/source/utils/asymptote/base/plain_pens.asy +++ b/Build/source/utils/asymptote/base/plain_pens.asy @@ -174,17 +174,29 @@ void write(file file=stdout, string s="", pen[] p) write(file,s,p[i],endl); } -pen font(string name) +void usetypescript(string s, string encoding="") { - return fontcommand("\font\ASYfont="+name+"\ASYfont"); + texpreamble("\usetypescript["+s+"]["+encoding+"]"); } -pen font(string name, real size) +pen font(string name, string options="") { + // Protect context switchtobodyfont with gsave/grestore to prevent + // misalignment if font is not found. + return fontcommand(settings.tex == "context" ? + "\special{pdf:q}\switchtobodyfont["+name+ + (options == "" ? "" : ","+options)+"]\special{pdf:Q}%" : + "\font\ASYfont="+name+"\ASYfont"); +} + +pen font(string name, real size, string options="") +{ + if(settings.tex == "context") + return fontsize(size)+font(name+","+(string) size+"pt",options); return fontsize(size)+font(name+" at "+(string) size+"pt"); } -pen font(string encoding, string family, string series="m", string shape="n") +pen font(string encoding, string family, string series, string shape) { return fontcommand("\usefont{"+encoding+"}{"+family+"}{"+series+"}{"+shape+ "}"); diff --git a/Build/source/utils/asymptote/base/plain_strings.asy b/Build/source/utils/asymptote/base/plain_strings.asy index 2df4743171f..801e63e83cf 100644 --- a/Build/source/utils/asymptote/base/plain_strings.asy +++ b/Build/source/utils/asymptote/base/plain_strings.asy @@ -136,29 +136,38 @@ string math(string s) return s != "" ? "$"+s+"$" : s; } +private void notimplemented(string text) +{ + abort(text+" is not implemented for the '"+settings.tex+"' TeX engine"); +} + string graphic(string name, string options="") { - if(options != "") options="["+options+"]"; - return "\includegraphics"+options+"{"+name+"}"; + if(latex()) { + if(options != "") options="["+options+"]"; + return "\includegraphics"+options+"{"+name+"}"; + } + if(settings.tex != "context") + notimplemented("graphic"); + return "\externalfigure["+name+"]["+options+"]"; } string minipage(string s, real width=100bp) { if(latex()) return "\begin{minipage}{"+(string) (width*pt)+"pt}"+s+"\end{minipage}"; - write("warning: minipage requires -tex latex or -tex pdflatex"); - return ""; + if(settings.tex != "context") + notimplemented("minipage"); + return "\startframedtext[none][frame=off,width="+(string) (width*pt)+ + "pt]"+s+"\stopframedtext"; } void usepackage(string s, string options="") { - if(latex()) { - string usepackage="\usepackage"; - if(options != "") usepackage += "["+options+"]"; - texpreamble(usepackage+"{"+s+"}"); - return; - } - write("warning: usepackage requires -tex latex or -tex pdflatex"); + if(!latex()) notimplemented("usepackage"); + string usepackage="\usepackage"; + if(options != "") usepackage += "["+options+"]"; + texpreamble(usepackage+"{"+s+"}"); } void pause(string w="Hit enter to continue") diff --git a/Build/source/utils/asymptote/base/three.asy b/Build/source/utils/asymptote/base/three.asy index 7c76714518a..a5a78a77b2a 100644 --- a/Build/source/utils/asymptote/base/three.asy +++ b/Build/source/utils/asymptote/base/three.asy @@ -6,6 +6,7 @@ if(prc0()) { access embed; Embed=embed.embed; Link=embed.link; + if(settings.tex == "context") settings.prc=false; } real defaultshininess=0.25; @@ -14,9 +15,10 @@ real linegranularity=0.01; real tubegranularity=0.003; real dotgranularity=0.0001; pair viewportmargin=0; // Horizontal and vertical viewport margins. -real viewportfactor=1.02; // Factor used to expand orthographic viewport. -real anglefactor=1.02; // Factor used to expand perspective viewport. +real viewportfactor=1.005; // Factor used to expand orthographic viewport. real angleprecision=1e-3; // Precision for centering perspective projections. +real anglefactor=max(1.015,1+angleprecision); + // Factor used to expand perspective viewport. string defaultembed3Doptions; string defaultembed3Dscript; @@ -299,6 +301,13 @@ projection obliqueY(real angle=45) projection oblique=oblique(); projection obliqueX=obliqueX(), obliqueY=obliqueY(), obliqueZ=obliqueZ(); +projection LeftView=orthographic(-X,showtarget=true); +projection RightView=orthographic(X,showtarget=true); +projection FrontView=orthographic(-Y,showtarget=true); +projection BackView=orthographic(Y,showtarget=true); +projection BottomView=orthographic(-Z,showtarget=true); +projection TopView=orthographic(Z,showtarget=true); + currentprojection=perspective(5,4,2); // Map pair z to a triple by inverting the projection P onto the @@ -1790,10 +1799,8 @@ restricted path3 unitsquare3=O--X--X+Y--Y--cycle; path3 circle(triple c, real r, triple normal=Z) { - path3 p=scale3(r)*unitcircle3; - if(normal != Z) - p=align(unit(normal))*p; - return shift(c)*p; + path3 p=normal == Z ? unitcircle3 : align(unit(normal))*unitcircle3; + return shift(c)*scale3(r)*p; } // return an arc centered at c from triple v1 to v2 (assuming |v2-c|=|v1-c|), @@ -1811,10 +1818,14 @@ path3 arc(triple c, triple v1, triple v2, triple normal=O, bool direction=CCW) if(normal == O) abort("explicit normal required for these endpoints"); } - transform3 T=align(unit(normal)); - transform3 Tinv=transpose(T); - v1=Tinv*v1; - v2=Tinv*v2; + transform3 T; + bool align=normal != Z; + if(align) { + T=align(unit(normal)); + transform3 Tinv=transpose(T); + v1=Tinv*v1; + v2=Tinv*v2; + } string invalidnormal="invalid normal vector"; real fuzz=sqrtEpsilon*max(abs(v1),abs(v2)); @@ -1833,7 +1844,9 @@ path3 arc(triple c, triple v1, triple v2, triple normal=O, bool direction=CCW) if(t1 >= t2 && direction) t1 -= n; if(t2 >= t1 && !direction) t2 -= n; - return shift(c)*scale3(r)*T*subpath(unitcircle3,t1,t2); + path3 p=subpath(unitcircle3,t1,t2); + if(align) p=T*p; + return shift(c)*scale3(r)*p; } // return an arc centered at c with radius r from c+r*dir(theta1,phi1) to @@ -2469,7 +2482,7 @@ object embed(string label="", string text=label, transform3 inv=inverse(modelview); if(adjusted) write("adjusting camera to ",tinv*inv*P.camera); - target=inv*P.target; + target=inv*P.target; } P=T*P; } @@ -2590,6 +2603,23 @@ currentpicture.fitter=new frame(string prefix, picture pic, string format, return f; }; +void addViews(picture dest, picture src, bool group=true, + filltype filltype=NoFill, bool above=true) +{ + frame Front=src.fit(FrontView); + add(dest,Front,group,filltype,above); + frame Top=src.fit(TopView); + add(dest,shift(0,min(Front).y-max(Top).y)*Top,group,filltype,above); + frame Right=src.fit(RightView); + add(dest,shift(min(Front).x-max(Right).x)*Right,group,filltype,above); +} + +void addViews(picture src, bool group=true, filltype filltype=NoFill, + bool above=true) +{ + addViews(currentpicture,src,group,filltype,above); +} + // Force an array of 3D pictures to be as least as large as picture all. void rescale3(picture[] pictures, picture all, projection P=currentprojection) { diff --git a/Build/source/utils/asymptote/base/three_surface.asy b/Build/source/utils/asymptote/base/three_surface.asy index 6e540c416ff..f1303d2e973 100644 --- a/Build/source/utils/asymptote/base/three_surface.asy +++ b/Build/source/utils/asymptote/base/three_surface.asy @@ -35,14 +35,6 @@ struct patch { return new real[] {f(P[0][0]),f(P[0][3]),f(P[3][3]),f(P[3][0])}; } - triple[] controlpoints() { - return new triple[] { - P[0][0],P[0][1],P[0][2],P[0][3], - P[1][0],P[1][1],P[1][2],P[1][3], - P[2][0],P[2][1],P[2][2],P[2][3], - P[3][0],P[3][1],P[3][2],P[3][3]}; - } - triple Bu(int j, real u) {return bezier(P[0][j],P[1][j],P[2][j],P[3][j],u);} triple BuP(int j, real u) {return bezierP(P[0][j],P[1][j],P[2][j],P[3][j],u);} triple BuPP(int j, real u) { @@ -145,22 +137,6 @@ struct patch { light.color(normal10(),nocolors ? m : colors[3])}; } - triple bound(real m(real[], real), triple b) { - real x=m(new real[] {P[0][0].x,P[0][1].x,P[0][2].x,P[0][3].x, - P[1][0].x,P[1][1].x,P[1][2].x,P[1][3].x, - P[2][0].x,P[2][1].x,P[2][2].x,P[2][3].x, - P[3][0].x,P[3][1].x,P[3][2].x,P[3][3].x},b.x); - real y=m(new real[] {P[0][0].y,P[0][1].y,P[0][2].y,P[0][3].y, - P[1][0].y,P[1][1].y,P[1][2].y,P[1][3].y, - P[2][0].y,P[2][1].y,P[2][2].y,P[2][3].y, - P[3][0].y,P[3][1].y,P[3][2].y,P[3][3].y},b.y); - real z=m(new real[] {P[0][0].z,P[0][1].z,P[0][2].z,P[0][3].z, - P[1][0].z,P[1][1].z,P[1][2].z,P[1][3].z, - P[2][0].z,P[2][1].z,P[2][2].z,P[2][3].z, - P[3][0].z,P[3][1].z,P[3][2].z,P[3][3].z},b.z); - return (x,y,z); - } - triple min3,max3; bool havemin3,havemax3; @@ -172,13 +148,13 @@ struct patch { triple min(triple bound=P[0][0]) { if(havemin3) return minbound(min3,bound); havemin3=true; - return min3=bound(minbound,bound); + return min3=minbound(P,bound); } triple max(triple bound=P[0][0]) { if(havemax3) return maxbound(max3,bound); havemax3=true; - return max3=bound(maxbound,bound); + return max3=maxbound(P,bound); } triple center() { @@ -186,11 +162,11 @@ struct patch { } pair min(projection P, pair bound=project(this.P[0][0],P.t)) { - return minbound(controlpoints(),P.t,bound); + return minbound(this.P,P.t,bound); } pair max(projection P, pair bound=project(this.P[0][0],P.t)) { - return maxbound(controlpoints(),P.t,bound); + return maxbound(this.P,P.t,bound); } void operator init(triple[][] P, triple[] normals=new triple[], @@ -901,6 +877,45 @@ patch subpatch(patch s, real ua, real va, real ub, real vb) s.straight,s.planar); } +// return an array containing all intersection times of path p and patch s. +real[][] intersections(path3 p, patch s, real fuzz=-1) +{ + return sort(intersections(p,s.P,fuzz)); +} + +// return an array containing all intersection times of path p and surface s. +real[][] intersections(path3 p, surface s, real fuzz=-1) +{ + real[][] T; + if(length(p) < 0) return T; + for(int i=0; i < s.s.length; ++i) + for(real[] s: intersections(p,s.s[i].P,fuzz)) + T.push(s); + + sort(T); + + static real fuzzFactor=10.0; + static real Fuzz=1000.0*realEpsilon; + real fuzz=max(fuzzFactor*fuzz,Fuzz)*abs(max(s)-min(s)); + + // Remove intrapatch duplicate points. + for(int i=0; i < T.length; ++i) { + for(int j=i+1; j < T.length;) { + if(abs(point(p,i)-point(p,j)) < fuzz) + T.delete(j); + else ++j; + } + } + return T; +} + +// return an array containing all intersection points of path p and surface s. +triple[] intersectionpoints(path3 p, surface s, real fuzz=-1) +{ + real[][] t=intersections(p,s,fuzz); + return sequence(new triple(int i) {return point(p,t[i][0]);},t.length); +} + triple point(patch s, real u, real v) { return s.point(u,v); @@ -1152,6 +1167,12 @@ void label(picture pic=currentpicture, Label L, triple position, path[] g=texpath(L); if(g.length == 0 || (g.length == 1 && size(g[0]) == 0)) return; pic.add(new void(frame f, transform3 t, picture pic, projection P) { + // Handle relative projected 3D alignments. + Label L=L.copy(); + if(!align.is3D && L.align.relative && L.align.dir3 != O && + determinant(P.t) != 0) + L.align(L.align.dir*unit(project(L.align.dir3,P.t))); + triple v=t*position; if(L.defaulttransform3) L.T3=transform3(P); @@ -1181,20 +1202,21 @@ void label(picture pic=currentpicture, Label L, triple position, void label(picture pic=currentpicture, Label L, path3 g, align align=NoAlign, pen p=currentpen) { - Label L=Label(L,align,p); + Label L=L.copy(); + L.align(align); + L.p(p); bool relative=L.position.relative; real position=L.position.position.x; - pair Align=L.align.dir; - bool alignrelative=L.align.relative; if(L.defaultposition) {relative=true; position=0.5;} if(relative) position=reltime(g,position); if(L.align.default) { - alignrelative=true; - Align=position <= 0 ? S : position >= length(g) ? N : E; + align a; + a.init(-I*(position <= sqrtEpsilon ? S : + position >= length(g)-sqrtEpsilon ? N : E),relative=true); + a.dir3=dir(g,position); // Pass 3D direction via unused field. + L.align(a); } - label(pic,L,point(g,position), - alignrelative && determinant(currentprojection.t) != 0 ? - -Align*project(dir(g,position),currentprojection.t)*I : L.align); + label(pic,L,point(g,position)); } surface extrude(Label L, triple axis=Z) diff --git a/Build/source/utils/asymptote/base/version.asy b/Build/source/utils/asymptote/base/version.asy index 6f560eb187d..0a43cd5ee23 100644 --- a/Build/source/utils/asymptote/base/version.asy +++ b/Build/source/utils/asymptote/base/version.asy @@ -1 +1 @@ -string VERSION="1.73"; +string VERSION="1.74"; -- cgit v1.2.3