comment framed views endcomment function getframe (x,y,z) ## gets a box around all points in (x,y,z). ex=extrema(x); ey=extrema(y); ez=extrema(z); return [min(ex[:,1]'),max(ex[:,3]'), min(ey[:,1]'),max(ey[:,3]'),min(ez[:,1]'),max(ez[:,3]')] endfunction function framez0 (f) wire([f[1],f[2],f[2],f[1],f[1]], .. [f[3],f[3],f[4],f[4],f[3]],dup(f[5],5)'); .. grid3d(f); return 0 endfunction function framez1 (f) wire([f[1],f[2],f[2],f[1],f[1]], .. [f[3],f[3],f[4],f[4],f[3]],dup(f[6],5)'); return 0 endfunction function framexpyp (f) wire([f[2],f[2]],[f[4],f[4]],[f[5],f[6]]); return 0 endfunction function framexpym (f) wire([f[2],f[2]],[f[3],f[3]],[f[5],f[6]]); return 0 endfunction function framexmyp (f) wire([f[1],f[1]],[f[4],f[4]],[f[5],f[6]]); return 0 endfunction function framexmym (f) wire([f[1],f[1]],[f[3],f[3]],[f[5],f[6]]); return 0 endfunction function xgrid3d(f,tx,xfactor,yz=3,color=3) ## draws a grid for x axis in the plane y or z = f[yz] nx=cols(tx); ls=linestyle(".");lw=linewidth(1);c=color(color); loop 1 to nx; if yz==3||yz==4; .. plane y=cst wire([tx[#],tx[#]],[f[yz],f[yz]],[f[5],f[6]]); else wire([tx[#],tx[#]],[f[3],f[4]],[f[yz],f[yz]]); endif; end; color(c);linewidth(lw);linestyle(ls); return 0; endfunction function ygrid3d(f,ty,yfactor,xz=1,color=3) ## draws a grid for y axis in the plane x or z = f[xz] ny=cols(ty); ls=linestyle(".");lw=linewidth(1);c=color(color); loop 1 to ny; if xz==1||xz==2; .. plane x=cst wire([f[xz],f[xz]],[ty[#],ty[#]],[f[5],f[6]]); else wire([f[1],f[2]],[ty[#],ty[#]],[f[xz],f[xz]]); endif; end; color(c);linewidth(lw);linestyle(ls); return 0; endfunction function zgrid3d(f,tz,zfactor,xy=1,color=3) ## draws a grid for z axis in the plane x or y = f[xy] nz=cols(tz); ls=linestyle(".");lw=linewidth(1);c=color(color); loop 1 to nz; if xy==1||xy==2; .. plane x=cst wire([f[xy],f[xy]],[f[3],f[4]],[tz[#],tz[#]]); else wire([f[1],f[2]],[f[xy],f[xy]],[tz[#],tz[#]]); endif; end; color(c);linewidth(lw);linestyle(ls); return 0; endfunction function xticks3d(f,tx,xfactor,ctr,color=3) ## draws a grid for z axis in the plane x or y = f[xy] nx=cols(tx); w=window(); ht=textheight(); ls=linestyle(".");lw=linewidth(1);c=color(color); y=[f[3],f[3],f[4],f[4]]; z=[f[5],f[6],f[5],f[6]]; {c,r}=project(dup(f[1],4)',y,z); cmax=max(r); loop 1 to 4 if r[#]==cmax; if y[#]==f[3]; {xp,yp}=project(tx,dup(y[#]-(!ctr)*(f[4]-f[3])/20,nx)',dup(z[#]-ctr*(f[6]-f[5])/20,nx)'); else {xp,yp}=project(tx,dup(y[#]+(!ctr)*(f[4]-f[3])/20,nx)',dup(z[#]-ctr*(f[6]-f[5])/20,nx)'); endif; break; endif; end; loop 1 to nx; _ctext(niceform(tx[#]/xfactor),[xp[#],yp[#]]); end; .. if ticks && !(f~=1); .. _ctext("* "|printscale(f),[(w[1]+w[3])/2,w[4]+1.5*ht]); .. endif; color(c);linewidth(lw);linestyle(ls); return 0; endfunction function yticks3d(f,ty,yfactor,ctr,color=3) ## draws a grid for z axis in the plane x or y = f[xy] ny=cols(ty); w=window(); ht=textheight(); ls=linestyle(".");lw=linewidth(1);c=color(color); x=[f[1],f[1],f[2],f[2]]; z=[f[5],f[6],f[5],f[6]]; {c,r}=project(x,dup(f[3],4)',z); cmax=max(r); loop 1 to 4 if r[#]==cmax; if x[#]==f[1]; {xp,yp}=project(dup(x[#]-(!ctr)*(f[2]-f[1])/20,ny)',ty,dup(z[#]-ctr*(f[6]-f[5])/20,ny)'); else {xp,yp}=project(dup(x[#]+(!ctr)*(f[2]-f[1])/20,ny)',ty,dup(z[#]-ctr*(f[6]-f[5])/20,ny)'); endif; break; endif; end; loop 1 to ny; _ctext(niceform(ty[#]/yfactor),[xp[#],yp[#]]); end; .. if ticks && !(f~=1); .. _ctext("* "|printscale(f),[(w[1]+w[3])/2,w[4]+1.5*ht]); .. endif; color(c);linewidth(lw);linestyle(ls); return 0; endfunction function zticks3d(f,tz,zfactor,color=3) ## draws a grid for z axis in the plane x or y = f[xy] nz=cols(tz); w=window(); ht=textheight(); ls=linestyle(".");lw=linewidth(1);c=color(color); x=[f[1],f[2],f[1],f[2]]; y=[f[3],f[3],f[4],f[4]]; {c,r}=project(x,y,dup(f[5],4)'); cmin=min(c); loop 1 to 4 if c[#]==cmin; {xp,yp}=project(dup(x[#],nz+1)',dup(y[#],nz+1)',tz|tz[nz]+(tz[nz]-tz[nz-1])); break; endif; end; loop 1 to nz; _rtext(niceform(tz[#]/zfactor),[xp[#]-5,yp[#]-ht/2]); end; .. if !(zfactor~=1); .. _rtext("* "|printscale(zfactor),[xp[nz+1]-5,yp[nz+1]-ht/2]); .. endif; color(c);linewidth(lw);linestyle(ls); return 0; endfunction function frame1 (f,grid=0,ticks=0,tx=0,ty=0,tz=0,xfactor=1,yfactor=1,zfactor=1) ## draws the back part of the box (considering view) v=view(); x=sin(v[3])*v[1]; y=-cos(v[3])*v[1]; if x<=f[2]; framexpyp(f); framexpym(f); if grid; zgrid3d(f,tz,zfactor,2); ygrid3d(f,ty,yfactor,2); endif; endif; if x>=f[1]; framexmyp(f); framexmym(f); if grid; zgrid3d(f,tz,zfactor,1); ygrid3d(f,ty,yfactor,1); endif; endif; if y<=f[4]; framexmyp(f); framexpyp(f); if grid; zgrid3d(f,tz,zfactor,4); xgrid3d(f,tx,xfactor,4); endif; endif; if y>=f[3]; framexmym(f); framexpym(f); if grid; zgrid3d(f,tz,zfactor,3); xgrid3d(f,tx,xfactor,3); endif; endif; if ticks; zticks3d(f,tz,zfactor); endif; y=sin(v[4])*v[1];ctr=0; if y>f[5]; framez0(f); if grid; xgrid3d(f,tx,xfactor,5); ygrid3d(f,ty,yfactor,5); endif; endif; if y=f[6]; framez1(f); endif; x=sin(v[3])*v[1]; y=-cos(v[3])*v[1]; if x>=f[2]; framexpyp(f); framexpym(f); endif; if x<=f[1]; framexmyp(f); framexmym(f); endif; if y>=f[4]; framexmyp(f); framexpyp(f); endif; if y<=f[3]; framexmym(f); framexpym(f); endif; return 0 endfunction function scaleframe (x,y,z,f,m) s=max([f[2]-f[1],f[4]-f[3],f[6]-f[5]]); xm=(f[2]+f[1])/2; ym=(f[4]+f[3])/2; zm=(f[6]+f[5])/2; ff=m/s*2; f=[f[1]-xm,f[2]-xm,f[3]-ym,f[4]-ym,f[5]-zm,f[6]-zm]*ff; return {(x-xm)*ff,(y-ym)*ff,(z-zm)*ff} endfunction function framedsolid (x,y,z,scale=0,grid=1,ticks=1) ## works like solid and draws a frame around the plot ## if scale is specified, then the plot is scaled to fit into a cube of ## side length 2*scale centered at 0 frame=getframe(x,y,z); if !holding(); clg; endif; h=holding(1); if scale; {x1,y1,z1}=scaleframe(x,y,z,frame,scale); else; {x1,y1,z1}={x,y,z}; endif; if grid || ticks; {tx,xfactor}=ticks(frame[1],frame[2]); {ty,yfactor}=ticks(frame[3],frame[4]); {tz,zfactor}=ticks(frame[5],frame[6]); color(2);frame1(frame,grid,ticks,tx,ty,tz,xfactor,yfactor,zfactor); color(1); solid(x1,y1,z1); color(2); frame2(frame); color(1); else color(2); frame1(frame); color(1); solid(x1,y1,z1); color(2); frame2(frame); color(1); endif; holding(h); return frame endfunction function framedsolidhue (x,y,z,hue,scale=0,f=1,grid=1,ticks=1) ## works like solidhue and draws a frame around the plot ## if scale is specified, then the plot is scaled to fit into a cube of ## side length 2*scale centered at 0 frame=getframe(x,y,z); if !holding(); clg; endif; h=holding(1); if scale; {x1,y1,z1}=scaleframe(x,y,z,frame,scale); else; {x1,y1,z1}={x,y,z}; endif; if grid || ticks; {tx,xfactor}=ticks(frame[1],frame[2]); {ty,yfactor}=ticks(frame[3],frame[4]); {tz,zfactor}=ticks(frame[5],frame[6]); color(2);frame1(frame,grid,ticks,tx,ty,tz,xfactor,yfactor,zfactor); color(1); if f; solidhue(x1,y1,z1,hue,f); else; solidhue(x1,y1,z1,hue); endif; color(2); frame2(frame); color(1); else color(2); frame1(frame); color(1); if f; solidhue(x1,y1,z1,hue,f); else; solidhue(x1,y1,z1,hue); endif; color(2); frame2(frame); color(1); endif; holding(h); return frame endfunction function framedwire (x,y,z,scale=0,grid=0,ticks=1) ## works like framedsolid frame=getframe(x,y,z); if !holding(); clg; endif; h=holding(1); if scale; {x1,y1,z1}=scaleframe(x,y,z,frame,scale); else; {x1,y1,z1}={x,y,z}; endif; if grid || ticks; {tx,xfactor}=ticks(frame[1],frame[2]); {ty,yfactor}=ticks(frame[3],frame[4]); {tz,zfactor}=ticks(frame[5],frame[6]); color(2);frame1(frame,grid,ticks,tx,ty,tz,xfactor,yfactor,zfactor); color(1); wire(x1,y1,z1); color(2); frame2(frame); color(1); else color(2); frame1(frame); color(1); wire(x1,y1,z1); color(2); frame2(frame); color(1); endif; holding(h); return frame endfunction function framedmark3 (x,y,z,scale=0,grid=1,ticks=1) ## Plots points in three dimensions with frame. ## x,y,z must be 1xn vectors. frame=getframe(x,y,z); if !holding(); clg; endif; h=holding(1); if scale; {x1,y1,z1}=scaleframe(x,y,z,frame,scale); else {x1,y1,z1}={x,y,z}; endif if grid || ticks; {tx,xfactor}=ticks(frame[1],frame[2]); {ty,yfactor}=ticks(frame[3],frame[4]); {tz,zfactor}=ticks(frame[5],frame[6]); color(2);frame1(frame,grid,ticks,tx,ty,tz,xfactor,yfactor,zfactor); color(1); {c0,r0}=project(x1,y1,z1); {x0,y0}=fromscreen(c0,r0); mark(x0,y0); color(2); frame2(frame); color(1); else color(2); frame1(frame); color(1); {c0,r0}=project(x1,y1,z1); {x0,y0}=fromscreen(c0,r0); mark(x0,y0); color(2); frame2(frame); color(1); endif; holding(h); return frame; endfunction