diff options
Diffstat (limited to 'Build/source/utils/asymptote/base/graph3.asy')
-rw-r--r-- | Build/source/utils/asymptote/base/graph3.asy | 341 |
1 files changed, 200 insertions, 141 deletions
diff --git a/Build/source/utils/asymptote/base/graph3.asy b/Build/source/utils/asymptote/base/graph3.asy index 1fe63490c9b..f690c6a3c10 100644 --- a/Build/source/utils/asymptote/base/graph3.asy +++ b/Build/source/utils/asymptote/base/graph3.asy @@ -9,7 +9,7 @@ direction3 Dir(triple dir) {return new triple(real) {return dir;};} ticklocate ticklocate(real a, real b, autoscaleT S=defaultS, real tickmin=-infinity, real tickmax=infinity, - real time(real)=null, direction3 dir) + real time(real)=null, direction3 dir) { if((valuetime) time == null) time=linear(S.T(),a,b); ticklocate locate; @@ -23,13 +23,13 @@ ticklocate ticklocate(real a, real b, autoscaleT S=defaultS, locate.dir3=dir; return locate; } - + private struct locateT { real t; // tick location time triple V; // tick location in frame coordinates triple pathdir; // path direction in frame coordinates triple dir; // tick direction in frame coordinates - + void dir(transform3 T, path3 g, ticklocate locate, real t) { pathdir=unit(shiftless(T)*dir(g,t)); triple Dir=locate.dir3(t); @@ -60,7 +60,7 @@ void drawtick(picture pic, transform3 T, path3 g, path3 g2, draw(pic,G,p,name="tick"); } -triple ticklabelshift(triple align, pen p=currentpen) +triple ticklabelshift(triple align, pen p=currentpen) { return 0.25*unit(align)*labelmargin(p); } @@ -100,10 +100,10 @@ void labeltick(picture pic, transform3 T, path3 g, if(s != "") label(pic,F.defaulttransform3 ? baseline(s,baselinetemplate) : F.T3*s,v, align,F.p); -} +} // Add axis label L to frame f. -void labelaxis(picture pic, transform3 T, Label L, path3 g, +void labelaxis(picture pic, transform3 T, Label L, path3 g, ticklocate locate=null, int sign=1, bool ticklabels=false) { triple m=pic.min(identity4); @@ -118,7 +118,7 @@ void labelaxis(picture pic, transform3 T, Label L, path3 g, picture F; if(L.align.dir3 == O) align=unit(invert(L.align.dir,v,P))*abs(L.align.dir); - + if(ticklabels && locate != null && piecewisestraight(g)) { locateT locate1; locate1.dir(T,g,locate,t); @@ -171,25 +171,25 @@ ticks3 Ticks3(int sign, Label F="", ticklabel ticklabel=null, pen pTick=pTick; pen ptick=ptick; ticklabel ticklabel=ticklabel; - + real Size=Size; real size=size; if(Size == 0) Size=Ticksize; if(size == 0) size=ticksize; - + Label L=L.copy(); Label F=F.copy(); L.p(p); F.p(p); if(pTick == nullpen) pTick=p; if(ptick == nullpen) ptick=pTick; - + bool ticklabels=false; path3 G=t*g; path3 G2=t*g2; - + scalefcn T; - + real a,b; if(locate.S.scale.logarithmic) { a=locate.S.postscale.Tinv(locate.a); @@ -200,11 +200,11 @@ ticks3 Ticks3(int sign, Label F="", ticklabel ticklabel=null, b=locate.S.Tinv(locate.b); T=identity; } - + if(a > b) {real temp=a; a=b; b=temp;} real norm=max(abs(a),abs(b)); - + string format=autoformat(F.s,norm...Ticks); if(F.s == "%") F.s=""; if(ticklabel == null) { @@ -324,8 +324,8 @@ ticks3 InOutTicks(Label format="", ticklabel ticklabel=null, begin,end,modify,Size,size,extend,pTick,ptick); } -ticks3 InTicks(Label format="", ticklabel ticklabel=null, - bool beginlabel=true, bool endlabel=true, +ticks3 InTicks(Label format="", ticklabel ticklabel=null, + bool beginlabel=true, bool endlabel=true, real[] Ticks, real[] ticks=new real[], real Size=0, real size=0, bool extend=false, pen pTick=nullpen, pen ptick=nullpen) @@ -334,8 +334,8 @@ ticks3 InTicks(Label format="", ticklabel ticklabel=null, Ticks,ticks,Size,size,extend,pTick,ptick); } -ticks3 OutTicks(Label format="", ticklabel ticklabel=null, - bool beginlabel=true, bool endlabel=true, +ticks3 OutTicks(Label format="", ticklabel ticklabel=null, + bool beginlabel=true, bool endlabel=true, real[] Ticks, real[] ticks=new real[], real Size=0, real size=0, bool extend=false, pen pTick=nullpen, pen ptick=nullpen) @@ -344,8 +344,8 @@ ticks3 OutTicks(Label format="", ticklabel ticklabel=null, Ticks,ticks,Size,size,extend,pTick,ptick); } -ticks3 InOutTicks(Label format="", ticklabel ticklabel=null, - bool beginlabel=true, bool endlabel=true, +ticks3 InOutTicks(Label format="", ticklabel ticklabel=null, + bool beginlabel=true, bool endlabel=true, real[] Ticks, real[] ticks=new real[], real Size=0, real size=0, bool extend=false, pen pTick=nullpen, pen ptick=nullpen) @@ -362,15 +362,15 @@ InOutTicks=InOutTicks(); triple tickMin3(picture pic) { return minbound(pic.userMin(),(pic.scale.x.tickMin,pic.scale.y.tickMin, - pic.scale.z.tickMin)); + pic.scale.z.tickMin)); } - + triple tickMax3(picture pic) { return maxbound(pic.userMax(),(pic.scale.x.tickMax,pic.scale.y.tickMax, - pic.scale.z.tickMax)); + pic.scale.z.tickMax)); } - + axis Bounds(int type=Both, int type2=Both, triple align=O, bool extend=false) { return new void(picture pic, axisT axis) { @@ -470,22 +470,22 @@ XYZero=XYZero(); void axis(picture pic=currentpicture, Label L="", path3 g, path3 g2=nullpath3, pen p=currentpen, ticks3 ticks, ticklocate locate, arrowbar3 arrow=None, margin3 margin=NoMargin3, - int[] divisor=new int[], bool above=false, bool opposite=false) + int[] divisor=new int[], bool above=false, bool opposite=false) { Label L=L.copy(); real t=reltime(g,0.5); if(L.defaultposition) L.position(t); divisor=copy(divisor); locate=locate.copy(); - + pic.add(new void (picture f, transform3 t, transform3 T, triple, triple) { picture d; ticks(d,t,L,g,g2,p,arrow,margin,locate,divisor,opposite,true); add(f,t*T*inverse(t)*d); },above=above); - + addPath(pic,g,p); - + if(L.s != "") { frame f; Label L0=L.copy(); @@ -552,7 +552,7 @@ void xaxis3At(picture pic=currentpicture, Label L="", axis axis, y0=y2; z0=z; } - + triple a2=xmin == -infinity ? tinv*(lb.x-min3(p).x,ytrans(t,y0), ztrans(t,z0)) : (xmin,y0,z0); triple b2=xmax == infinity ? tinv*(rt.x-max3(p).x,ytrans(t,y0), @@ -564,7 +564,7 @@ void xaxis3At(picture pic=currentpicture, Label L="", axis axis, pic.scale.x.tickMax=mx.max; divisor=mx.divisor; } - + triple fuzz=X*epsilon*max(abs(a.x),abs(b.x)); a -= fuzz; b += fuzz; @@ -584,7 +584,7 @@ void xaxis3At(picture pic=currentpicture, Label L="", axis axis, y=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax().y; else if(type == Both) { y2=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax().y; - y=opposite ? y2 : + y=opposite ? y2 : (pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin().y); } @@ -594,7 +594,7 @@ void xaxis3At(picture pic=currentpicture, Label L="", axis axis, z=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax().z; else if(type2 == Both) { z2=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax().z; - z=opposite2 ? z2 : + z=opposite2 ? z2 : (pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin().z); } @@ -610,7 +610,7 @@ void xaxis3At(picture pic=currentpicture, Label L="", axis axis, pic.addPoint(a,min3(p)); pic.addPoint(a,max3(p)); } - + if(finite(b)) { pic.addPoint(b,min3(p)); pic.addPoint(b,max3(p)); @@ -650,7 +650,7 @@ void xaxis3At(picture pic=currentpicture, Label L="", axis axis, pic.scale.x.bound.push(bounds); } -// An internal routine to draw an x axis at a particular y value. +// An internal routine to draw a y axis at a particular value. void yaxis3At(picture pic=currentpicture, Label L="", axis axis, real ymin=-infinity, real ymax=infinity, pen p=currentpen, ticks3 ticks=NoTicks3, @@ -685,19 +685,19 @@ void yaxis3At(picture pic=currentpicture, Label L="", axis axis, x0=x2; z0=z; } - + triple a2=ymin == -infinity ? tinv*(xtrans(t,x0),lb.y-min3(p).y, ztrans(t,z0)) : (x0,ymin,z0); triple b2=ymax == infinity ? tinv*(xtrans(t,x0),rt.y-max3(p).y, ztrans(t,z0)) : (x0,ymax,z0); - + if(ymin == -infinity || ymax == infinity) { bounds my=autoscale(a.y,b.y,pic.scale.y.scale); pic.scale.y.tickMin=my.min; pic.scale.y.tickMax=my.max; divisor=my.divisor; } - + triple fuzz=Y*epsilon*max(abs(a.y),abs(b.y)); a -= fuzz; b += fuzz; @@ -717,7 +717,7 @@ void yaxis3At(picture pic=currentpicture, Label L="", axis axis, x=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax().x; else if(type == Both) { x2=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax().x; - x=opposite ? x2 : + x=opposite ? x2 : (pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin().x); } @@ -727,7 +727,7 @@ void yaxis3At(picture pic=currentpicture, Label L="", axis axis, z=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax().z; else if(type2 == Both) { z2=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax().z; - z=opposite2 ? z2 : + z=opposite2 ? z2 : (pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin().z); } @@ -743,7 +743,7 @@ void yaxis3At(picture pic=currentpicture, Label L="", axis axis, pic.addPoint(a,min3(p)); pic.addPoint(a,max3(p)); } - + if(finite(b)) { pic.addPoint(b,min3(p)); pic.addPoint(b,max3(p)); @@ -783,7 +783,7 @@ void yaxis3At(picture pic=currentpicture, Label L="", axis axis, pic.scale.y.bound.push(bounds); } -// An internal routine to draw an x axis at a particular y value. +// An internal routine to draw a z axis at a particular value. void zaxis3At(picture pic=currentpicture, Label L="", axis axis, real zmin=-infinity, real zmax=infinity, pen p=currentpen, ticks3 ticks=NoTicks3, @@ -818,7 +818,7 @@ void zaxis3At(picture pic=currentpicture, Label L="", axis axis, x0=x2; y0=y; } - + triple a2=zmin == -infinity ? tinv*(xtrans(t,x0),ytrans(t,y0), lb.z-min3(p).z) : (x0,y0,zmin); triple b2=zmax == infinity ? tinv*(xtrans(t,x0),ytrans(t,y0), @@ -830,7 +830,7 @@ void zaxis3At(picture pic=currentpicture, Label L="", axis axis, pic.scale.z.tickMax=mz.max; divisor=mz.divisor; } - + triple fuzz=Z*epsilon*max(abs(a.z),abs(b.z)); a -= fuzz; b += fuzz; @@ -850,7 +850,7 @@ void zaxis3At(picture pic=currentpicture, Label L="", axis axis, x=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax().x; else if(type == Both) { x2=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax().x; - x=opposite ? x2 : + x=opposite ? x2 : (pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin().x); } @@ -860,7 +860,7 @@ void zaxis3At(picture pic=currentpicture, Label L="", axis axis, y=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax().y; else if(type2 == Both) { y2=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax().y; - y=opposite2 ? y2 : + y=opposite2 ? y2 : (pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin().y); } @@ -876,7 +876,7 @@ void zaxis3At(picture pic=currentpicture, Label L="", axis axis, pic.addPoint(a,min3(p)); pic.addPoint(a,max3(p)); } - + if(finite(b)) { pic.addPoint(b,min3(p)); pic.addPoint(b,max3(p)); @@ -934,7 +934,7 @@ void autoscale3(picture pic=currentpicture, axis axis) pic.userMaxz3(ceil(pic.userMax().z)); } } else {mz.min=mz.max=0; pic.scale.set=false;} - + pic.scale.z.tickMin=mz.min; pic.scale.z.tickMax=mz.max; axis.zdivisor=mz.divisor; @@ -948,7 +948,7 @@ void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero, arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=false) { if(xmin > xmax) return; - + if(pic.scale.x.automin && xmin > -infinity) pic.scale.x.automin=false; if(pic.scale.x.automax && xmax < infinity) pic.scale.x.automax=false; @@ -956,19 +956,19 @@ void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero, axis(pic,axis); autoscale3(pic,axis); } - + bool newticks=false; - + if(xmin != -infinity) { xmin=pic.scale.x.T(xmin); newticks=true; } - + if(xmax != infinity) { xmax=pic.scale.x.T(xmax); newticks=true; } - + if(newticks && pic.userSetx() && ticks != NoTicks3) { if(xmin == -infinity) xmin=pic.userMin().x; if(xmax == infinity) xmax=pic.userMax().x; @@ -977,16 +977,16 @@ void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero, pic.scale.x.tickMax=mx.max; axis.xdivisor=mx.divisor; } - + axis(pic,axis); - + if(xmin == -infinity && !axis.extend) { if(pic.scale.set) xmin=pic.scale.x.automin() ? pic.scale.x.tickMin : max(pic.scale.x.tickMin,pic.userMin().x); else xmin=pic.userMin().x; } - + if(xmax == infinity && !axis.extend) { if(pic.scale.set) xmax=pic.scale.x.automax() ? pic.scale.x.tickMax : @@ -998,7 +998,7 @@ void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero, L=L.copy(); L.position(axis.position); } - + bool back=false; if(axis.type == Both) { triple v=currentprojection.normal; @@ -1025,24 +1025,24 @@ void yaxis3(picture pic=currentpicture, Label L="", axis axis=XZZero, if(pic.scale.y.automin && ymin > -infinity) pic.scale.y.automin=false; if(pic.scale.y.automax && ymax < infinity) pic.scale.y.automax=false; - + if(!pic.scale.set) { axis(pic,axis); autoscale3(pic,axis); } - + bool newticks=false; - + if(ymin != -infinity) { ymin=pic.scale.y.T(ymin); newticks=true; } - + if(ymax != infinity) { ymax=pic.scale.y.T(ymax); newticks=true; } - + if(newticks && pic.userSety() && ticks != NoTicks3) { if(ymin == -infinity) ymin=pic.userMin().y; if(ymax == infinity) ymax=pic.userMax().y; @@ -1051,17 +1051,17 @@ void yaxis3(picture pic=currentpicture, Label L="", axis axis=XZZero, pic.scale.y.tickMax=my.max; axis.ydivisor=my.divisor; } - + axis(pic,axis); - + if(ymin == -infinity && !axis.extend) { if(pic.scale.set) ymin=pic.scale.y.automin() ? pic.scale.y.tickMin : max(pic.scale.y.tickMin,pic.userMin().y); else ymin=pic.userMin().y; } - - + + if(ymax == infinity && !axis.extend) { if(pic.scale.set) ymax=pic.scale.y.automax() ? pic.scale.y.tickMax : @@ -1073,7 +1073,7 @@ void yaxis3(picture pic=currentpicture, Label L="", axis axis=XZZero, L=L.copy(); L.position(axis.position); } - + bool back=false; if(axis.type == Both) { triple v=currentprojection.normal; @@ -1100,24 +1100,24 @@ void zaxis3(picture pic=currentpicture, Label L="", axis axis=XYZero, if(pic.scale.z.automin && zmin > -infinity) pic.scale.z.automin=false; if(pic.scale.z.automax && zmax < infinity) pic.scale.z.automax=false; - + if(!pic.scale.set) { axis(pic,axis); autoscale3(pic,axis); } - + bool newticks=false; - + if(zmin != -infinity) { zmin=pic.scale.z.T(zmin); newticks=true; } - + if(zmax != infinity) { zmax=pic.scale.z.T(zmax); newticks=true; } - + if(newticks && pic.userSetz() && ticks != NoTicks3) { if(zmin == -infinity) zmin=pic.userMin().z; if(zmax == infinity) zmax=pic.userMax().z; @@ -1126,16 +1126,16 @@ void zaxis3(picture pic=currentpicture, Label L="", axis axis=XYZero, pic.scale.z.tickMax=mz.max; axis.zdivisor=mz.divisor; } - + axis(pic,axis); - + if(zmin == -infinity && !axis.extend) { if(pic.scale.set) zmin=pic.scale.z.automin() ? pic.scale.z.tickMin : max(pic.scale.z.tickMin,pic.userMin().z); else zmin=pic.userMin().z; } - + if(zmax == infinity && !axis.extend) { if(pic.scale.set) zmax=pic.scale.z.automax() ? pic.scale.z.tickMax : @@ -1147,7 +1147,7 @@ void zaxis3(picture pic=currentpicture, Label L="", axis axis=XYZero, L=L.copy(); L.position(axis.position); } - + bool back=false; if(axis.type == Both) { triple v=currentprojection.vector(); @@ -1169,18 +1169,18 @@ void zlimits(picture pic=currentpicture, real min=-infinity, real max=infinity, bool crop=NoCrop) { if(min > max) return; - + pic.scale.z.automin=min <= -infinity; pic.scale.z.automax=max >= infinity; - + bounds mz; if(pic.scale.z.automin() || pic.scale.z.automax()) mz=autoscale(pic.userMin().z,pic.userMax().z,pic.scale.z.scale); - + if(pic.scale.z.automin) { if(pic.scale.z.automin()) pic.userMinz(mz.min); } else pic.userMinz(min(pic.scale.z.T(min),pic.scale.z.T(max))); - + if(pic.scale.z.automax) { if(pic.scale.z.automax()) pic.userMaxz(mz.max); } else pic.userMaxz(max(pic.scale.z.T(min),pic.scale.z.T(max))); @@ -1193,10 +1193,10 @@ void limits(picture pic=currentpicture, triple min, triple max) ylimits(pic,min.y,max.y); zlimits(pic,min.z,max.z); } - + // Draw x, y and z axes. void axes3(picture pic=currentpicture, - Label xlabel="", Label ylabel="", Label zlabel="", + Label xlabel="", Label ylabel="", Label zlabel="", bool extend=false, triple min=(-infinity,-infinity,-infinity), triple max=(infinity,infinity,infinity), @@ -1212,11 +1212,50 @@ triple Scale(picture pic=currentpicture, triple v) return (pic.scale.x.T(v.x),pic.scale.y.T(v.y),pic.scale.z.T(v.z)); } +triple[][] Scale(picture pic=currentpicture, triple[][] P) +{ + triple[][] Q=new triple[P.length][]; + for(int i=0; i < P.length; ++i) { + triple[] Pi=P[i]; + Q[i]=new triple[Pi.length]; + for(int j=0; j < Pi.length; ++j) + Q[i][j]=Scale(pic,Pi[j]); + } + return Q; +} + +real ScaleX(picture pic=currentpicture, real x) +{ + return pic.scale.x.T(x); +} + +real ScaleY(picture pic=currentpicture, real y) +{ + return pic.scale.y.T(y); +} + real ScaleZ(picture pic=currentpicture, real z) { return pic.scale.z.T(z); } +real[][] ScaleZ(picture pic=currentpicture, real[][] P) +{ + real[][] Q=new real[P.length][]; + for(int i=0; i < P.length; ++i) { + real[] Pi=P[i]; + Q[i]=new real[Pi.length]; + for(int j=0; j < Pi.length; ++j) + Q[i][j]=ScaleZ(pic,Pi[j]); + } + return Q; +} + +real[] uniform(real T(real x), real Tinv(real x), real a, real b, int n) +{ + return map(Tinv,uniform(T(a),T(b),n)); +} + // Draw a tick of length size at triple v in direction dir using pen p. void tick(picture pic=currentpicture, triple v, triple dir, real size=Ticksize, pen p=currentpen) @@ -1240,11 +1279,11 @@ void xtick3(picture pic=currentpicture, real x, triple dir=Y, real size=Ticksize, pen p=currentpen) { tick(pic,(x,pic.scale.y.scale.logarithmic ? 1 : 0, - pic.scale.z.scale.logarithmic ? 1 : 0),dir,size,p); + pic.scale.z.scale.logarithmic ? 1 : 0),dir,size,p); } void ytick(picture pic=currentpicture, triple v, triple dir=X, - real size=Ticksize, pen p=currentpen) + real size=Ticksize, pen p=currentpen) { tick(pic,v,dir,size,p); } @@ -1257,7 +1296,7 @@ void ytick3(picture pic=currentpicture, real y, triple dir=X, } void ztick(picture pic=currentpicture, triple v, triple dir=X, - real size=Ticksize, pen p=currentpen) + real size=Ticksize, pen p=currentpen) { xtick(pic,v,dir,size,p); } @@ -1294,7 +1333,7 @@ void xtick3(picture pic=currentpicture, Label L, real x, triple dir=Y, string format="", real size=Ticksize, pen p=currentpen) { xtick(pic,L,(x,pic.scale.y.scale.logarithmic ? 1 : 0, - pic.scale.z.scale.logarithmic ? 1 : 0),dir,size,p); + pic.scale.z.scale.logarithmic ? 1 : 0),dir,size,p); } void ytick(picture pic=currentpicture, Label L, triple v, triple dir=X, @@ -1307,7 +1346,7 @@ void ytick3(picture pic=currentpicture, Label L, real y, triple dir=X, string format="", real size=Ticksize, pen p=currentpen) { xtick(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,y, - pic.scale.z.scale.logarithmic ? 1 : 0),dir,format,size,p); + pic.scale.z.scale.logarithmic ? 1 : 0),dir,format,size,p); } void ztick(picture pic=currentpicture, Label L, triple v, triple dir=X, @@ -1320,7 +1359,7 @@ void ztick3(picture pic=currentpicture, Label L, real z, triple dir=X, string format="", real size=Ticksize, pen p=currentpen) { xtick(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0, - pic.scale.z.scale.logarithmic ? 1 : 0,z),dir,format,size,p); + pic.scale.z.scale.logarithmic ? 1 : 0,z),dir,format,size,p); } private void label(picture pic, Label L, triple v, real x, align align, @@ -1416,7 +1455,7 @@ multigraph graph(interpolate3 join, bool3 cond(real)) guide3 Straight(... guide3[])=operator --; guide3 Spline(... guide3[])=operator ..; - + guide3 graph(picture pic=currentpicture, real x(real), real y(real), real z(real), real a, real b, int n=ngraph, interpolate3 join=operator --) @@ -1519,12 +1558,12 @@ guide3 graph(triple F(path, real), path p, int n=1, guide3 graph(triple F(pair), path p, int n=1, interpolate3 join=operator --) { - return graph(new triple(path p, real position) + return graph(new triple(path p, real position) {return F(point(p,position));},p,n,join); } guide3 graph(picture pic=currentpicture, real f(pair), path p, int n=1, - interpolate3 join=operator --) + interpolate3 join=operator --) { return graph(new triple(pair z) {return Scale(pic,(z.x,z.y,f(z)));},p,n, join); @@ -1538,7 +1577,7 @@ guide3 graph(real f(pair), path p, int n=1, real T(pair), } // Connect points in v into segments corresponding to consecutive true elements -// of b using interpolation operator join. +// of b using interpolation operator join. path3[] segment(triple[] v, bool[] cond, interpolate3 join=operator --) { checkconditionlength(cond.length,v.length); @@ -1596,13 +1635,13 @@ bool vperiodic(triple[][] a) { } // return the surface described by a matrix f -surface surface(triple[][] f, bool[][] cond={}) +surface surface(picture pic=currentpicture, triple[][] f, bool[][] cond={}) { if(!rectangular(f)) abort("matrix is not rectangular"); - + int nx=f.length-1; int ny=nx > 0 ? f[0].length-1 : 0; - + bool all=cond.length == 0; int count; @@ -1632,7 +1671,11 @@ surface surface(triple[][] f, bool[][] cond={}) int[] indexi=s.index[i]; for(int j=0; j < ny; ++j) { if(all || (condi[j] && condi[j+1] && condp[j] && condp[j+1])) - s.s[++k]=patch(new triple[] {fi[j],fp[j],fp[j+1],fi[j+1]}); + s.s[++k]=patch(new triple[] { + Scale(pic,fi[j]), + Scale(pic,fp[j]), + Scale(pic,fp[j+1]), + Scale(pic,fi[j+1])}); indexi[j]=k; } } @@ -1708,14 +1751,15 @@ surface bispline(real[][] z, real[][] p, real[][] q, real[][] r, real zppmppp=zpp-hx*pp[jp]; real zijqij=zij+hy*qi[j]; real zpjqpj=zpj+hy*qp[j]; - + s.s[k]=patch(new triple[][] { - {(xi,yj,zij),(xi,y1,zijqij),(xi,y2,zip-qip),(xi,yp,zip)}, - {(x1,yj,zij+pij),(x1,y1,zijqij+pij+hxy*ri[j]), - (x1,y2,zippip-qip-hxy*ri[jp]),(x1,yp,zippip)}, - {(x2,yj,zpj-ppj),(x2,y1,zpjqpj-ppj-hxy*rp[j]), - (x2,y2,zppmppp-qpp+hxy*rp[jp]),(x2,yp,zppmppp)}, - {(xp,yj,zpj),(xp,y1,zpjqpj),(xp,y2,zpp-qpp),(xp,yp,zpp)}},copy=false); + {(xi,yj,zij),(xi,y1,zijqij),(xi,y2,zip-qip),(xi,yp,zip)}, + {(x1,yj,zij+pij),(x1,y1,zijqij+pij+hxy*ri[j]), + (x1,y2,zippip-qip-hxy*ri[jp]),(x1,yp,zippip)}, + {(x2,yj,zpj-ppj),(x2,y1,zpjqpj-ppj-hxy*rp[j]), + (x2,y2,zppmppp-qpp+hxy*rp[jp]),(x2,yp,zppmppp)}, + {(xp,yj,zpj),(xp,y1,zpjqpj),(xp,y2,zpp-qpp),(xp,yp,zpp)}}, + copy=false); indexi[j]=k; ++k; } @@ -1787,11 +1831,11 @@ private real[][][] bispline0(real[][] z, real[][] p, real[][] q, real[][] r, real zpjqpj=zpj+hy*qp[j]; s[k]=new real[][] {{zij,zijqij,zip-qip,zip}, - {zij+pij,zijqij+pij+hxy*ri[j], - zippip-qip-hxy*ri[jp],zippip}, - {zpj-ppj,zpjqpj-ppj-hxy*rp[j], - zppmppp-qpp+hxy*rp[jp],zppmppp}, - {zpj,zpjqpj,zpp-qpp,zpp}}; + {zij+pij,zijqij+pij+hxy*ri[j], + zippip-qip-hxy*ri[jp],zippip}, + {zpj-ppj,zpjqpj-ppj-hxy*rp[j], + zppmppp-qpp+hxy*rp[jp],zppmppp}, + {zpj,zpjqpj,zpp-qpp,zpp}}; ++k; } } @@ -1831,10 +1875,15 @@ real[][][] bispline(real[][] f, real[] x, real[] y, // return the surface described by a real matrix f, interpolated with // xsplinetype and ysplinetype. -surface surface(real[][] f, real[] x, real[] y, - splinetype xsplinetype=null, splinetype ysplinetype=xsplinetype, +surface surface(picture pic=currentpicture, real[][] f, real[] x, real[] y, + splinetype xsplinetype=null, + splinetype ysplinetype=xsplinetype, bool[][] cond={}) { + real[][] f=ScaleZ(pic,f); + real[] x=map(pic.scale.x.T,x); + real[] y=map(pic.scale.y.T,y); + real epsilon=sqrtEpsilon*norm(y); if(xsplinetype == null) xsplinetype=(abs(x[0]-x[x.length-1]) <= epsilon) ? periodic : notaknot; @@ -1863,8 +1912,9 @@ surface surface(real[][] f, real[] x, real[] y, // return the surface described by a real matrix f, interpolated with // xsplinetype and ysplinetype. -surface surface(real[][] f, pair a, pair b, splinetype xsplinetype, - splinetype ysplinetype=xsplinetype, bool[][] cond={}) +surface surface(picture pic=currentpicture, real[][] f, pair a, pair b, + splinetype xsplinetype, splinetype ysplinetype=xsplinetype, + bool[][] cond={}) { if(!rectangular(f)) abort("matrix is not rectangular"); @@ -1873,13 +1923,14 @@ surface surface(real[][] f, pair a, pair b, splinetype xsplinetype, if(nx == 0 || ny == 0) return nullsurface; - real[] x=uniform(a.x,b.x,nx); - real[] y=uniform(a.y,b.y,ny); - return surface(f,x,y,xsplinetype,ysplinetype,cond); + real[] x=uniform(pic.scale.x.T,pic.scale.x.Tinv,a.x,b.x,nx); + real[] y=uniform(pic.scale.y.T,pic.scale.y.Tinv,a.y,b.y,ny); + return surface(pic,f,x,y,xsplinetype,ysplinetype,cond); } // return the surface described by a real matrix f, interpolated linearly. -surface surface(real[][] f, pair a, pair b, bool[][] cond={}) +surface surface(picture pic=currentpicture, real[][] f, pair a, pair b, + bool[][] cond={}) { if(!rectangular(f)) abort("matrix is not rectangular"); @@ -1891,22 +1942,25 @@ surface surface(real[][] f, pair a, pair b, bool[][] cond={}) bool all=cond.length == 0; triple[][] v=new triple[nx+1][ny+1]; + + pair a=Scale(pic,a); + pair b=Scale(pic,b); for(int i=0; i <= nx; ++i) { - real x=interp(a.x,b.x,i/nx); + real x=pic.scale.x.Tinv(interp(a.x,b.x,i/nx)); bool[] condi=all ? null : cond[i]; triple[] vi=v[i]; real[] fi=f[i]; for(int j=0; j <= ny; ++j) if(all || condi[j]) - vi[j]=(x,interp(a.y,b.y,j/ny),fi[j]); + vi[j]=(x,pic.scale.y.Tinv(interp(a.y,b.y,j/ny)),fi[j]); } - return surface(v,cond); + return surface(pic,v,cond); } // return the surface described by a parametric function f over box(a,b), // interpolated linearly. -surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu, - bool cond(pair z)=null) +surface surface(picture pic=currentpicture, triple f(pair z), pair a, pair b, + int nu=nmesh, int nv=nu, bool cond(pair z)=null) { if(nu <= 0 || nv <= 0) return nullsurface; @@ -1921,23 +1975,25 @@ surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu, triple[][] v=new triple[nu+1][nv+1]; + pair a=Scale(pic,a); + pair b=Scale(pic,b); for(int i=0; i <= nu; ++i) { - real x=interp(a.x,b.x,i*du); + real x=pic.scale.x.Tinv(interp(a.x,b.x,i*du)); bool[] activei=all ? null : active[i]; triple[] vi=v[i]; for(int j=0; j <= nv; ++j) { - pair z=(x,interp(a.y,b.y,j*dv)); + pair z=(x,pic.scale.y.Tinv(interp(a.y,b.y,j*dv))); if(all || (activei[j]=cond(z))) vi[j]=f(z); } } - return surface(v,active); + return surface(pic,v,active); } - + // return the surface described by a parametric function f evaluated at u and v // and interpolated with usplinetype and vsplinetype. -surface surface(triple f(pair z), real[] u, real[] v, - splinetype[] usplinetype, splinetype[] vsplinetype=Spline, - bool cond(pair z)=null) +surface surface(picture pic=currentpicture, triple f(pair z), + real[] u, real[] v, splinetype[] usplinetype, + splinetype[] vsplinetype=Spline, bool cond(pair z)=null) { int nu=u.length-1; int nv=v.length-1; @@ -1960,7 +2016,7 @@ surface surface(triple f(pair z), real[] u, real[] v, for(int j=0; j <= nv; ++j) { pair z=(ui,v[j]); if(!all) activei[j]=cond(z); - triple f=f(z); + triple f=Scale(pic,f(z)); fxi[j]=f.x; fyi[j]=f.y; fzi[j]=f.z; @@ -2020,27 +2076,30 @@ surface surface(triple f(pair z), real[] u, real[] v, // return the surface described by a parametric function f over box(a,b), // interpolated with usplinetype and vsplinetype. -surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu, +surface surface(picture pic=currentpicture, triple f(pair z), pair a, pair b, + int nu=nmesh, int nv=nu, splinetype[] usplinetype, splinetype[] vsplinetype=Spline, bool cond(pair z)=null) { - return surface(f,uniform(a.x,b.x,nu),uniform(a.y,b.y,nv), - usplinetype,vsplinetype,cond); + real[] x=uniform(pic.scale.x.T,pic.scale.x.Tinv,a.x,b.x,nu); + real[] y=uniform(pic.scale.y.T,pic.scale.y.Tinv,a.y,b.y,nv); + return surface(pic,f,x,y,usplinetype,vsplinetype,cond); } // return the surface described by a real function f over box(a,b), // interpolated linearly. -surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx, - bool cond(pair z)=null) +surface surface(picture pic=currentpicture, real f(pair z), pair a, pair b, + int nx=nmesh, int ny=nx, bool cond(pair z)=null) { - return surface(new triple(pair z) {return (z.x,z.y,f(z));},a,b,nx,ny,cond); + return surface(pic,new triple(pair z) {return (z.x,z.y,f(z));},a,b,nx,ny, + cond); } // return the surface described by a real function f over box(a,b), // interpolated with xsplinetype and ysplinetype. -surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx, - splinetype xsplinetype, splinetype ysplinetype=xsplinetype, - bool cond(pair z)=null) +surface surface(picture pic=currentpicture, real f(pair z), pair a, pair b, + int nx=nmesh, int ny=nx, splinetype xsplinetype, + splinetype ysplinetype=xsplinetype, bool cond(pair z)=null) { bool[][] active; bool all=cond == null; @@ -2052,8 +2111,8 @@ surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx, pair dz=(dx,dy); real[][] F=new real[nx+1][ny+1]; - real[] x=uniform(a.x,b.x,nx); - real[] y=uniform(a.y,b.y,ny); + real[] x=uniform(pic.scale.x.T,pic.scale.x.Tinv,a.x,b.x,nx); + real[] y=uniform(pic.scale.y.T,pic.scale.y.Tinv,a.y,b.y,ny); for(int i=0; i <= nx; ++i) { bool[] activei=all ? null : active[i]; real[] Fi=F[i]; @@ -2064,7 +2123,7 @@ surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx, if(!all) activei[j]=cond(z); } } - return surface(F,x,y,xsplinetype,ysplinetype,active); + return surface(pic,F,x,y,xsplinetype,ysplinetype,active); } guide3[][] lift(real f(real x, real y), guide[][] g, @@ -2128,7 +2187,7 @@ void draw(picture pic=currentpicture, Label[] L=new Label[], render,interaction); } -real maxlength(triple f(pair z), pair a, pair b, int nu, int nv) +real maxlength(triple f(pair z), pair a, pair b, int nu, int nv) { return min(abs(f((b.x,a.y))-f(a))/nu,abs(f((a.x,b.y))-f(a))/nv); } |