plotimp3.red 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. module plotimp3; % Implicit plot: compute the varity {x,y,z|f(x,y,z)=0}.
  2. % Author: Herbert Melenk, ZIB Berlin.
  3. % data structure: cubes.
  4. symbolic procedure ploteval3impl(x,y,z);
  5. begin scalar rx,ry,rz,f,fcn;
  6. rx:=plotrange(x,
  7. reval(plot_xrange or '(!*interval!* -10 10)));
  8. ry:=plotrange(y,
  9. reval(plot_yrange or '(!*interval!* -10 10)));
  10. rz:=plotrange(z,
  11. reval(plot_zrange or '(!*interval!* -10 10)));
  12. fcn := car reverse plotfunctions!*;
  13. f:= ploteval3impl1(cdar plotfunctions!*,
  14. x,car rx,cadr rx,
  15. y,car ry,cadr ry,
  16. z,car rz,cadr rz);
  17. plotdriver(plot!-3exp!-reg,x,y,z,f);
  18. end;
  19. symbolic procedure ploteval3impl1(f,x,xlo,xhi,y,ylo,yhi,z,zlo,zhi);
  20. begin scalar u,dx,dy,dz,xx,yy,zz,l,ff,pts,val,w,q,qq,pt,found,done;
  21. integer nx,ny,nz;
  22. ff := rdwrap f;
  23. xlo:=rdwrap xlo; xhi:=rdwrap xhi;
  24. ylo:=rdwrap ylo; yhi:=rdwrap yhi;
  25. dx:=float(xhi-xlo)/float(nx:=plot!-points(x));
  26. dy:=float(yhi-ylo)/float(ny:=plot!-points(y));
  27. dz:=float(zhi-zlo)/float(nz:=plot!-points(z));
  28. pts := mk!-p!-array3(nx,ny,nz);
  29. val:= mk!-p!-array3(nx,ny,nz);
  30. % Step 1: compute a complete grid in 3d.
  31. for i:=0:nx do
  32. <<
  33. xx:=(xlo+i*dx);
  34. for j:=0:ny do
  35. <<
  36. yy:=(ylo+j*dy);
  37. for k:=0:nz do
  38. <<
  39. zz:=(zlo+k*dz);
  40. p!-put3(pts,i,j,k,{xx,yy,zz});
  41. u:=plotevalform(ff,f,{x . xx,y . yy,z . zz});
  42. if eqcar(u,'overflow) then u:=1.0;
  43. p!-put3(val,i,j,k,u);
  44. >>;
  45. >>
  46. >>;
  47. % Step 2: extract zero points.
  48. done := t;
  49. while done do
  50. <<done := nil; w:=
  51. for i:=0:nx #-1 collect
  52. for j:=0:ny #-1 collect
  53. <<q:=nil; found:=nil;
  54. pt := p!-get3(pts,i,j,1);
  55. for k:=nz step -1 until 0 do
  56. if null found then
  57. <<if null q then q:=p!-get3(val,i,j,k);
  58. qq:=p!-get3(val,i,j,k);
  59. if q and qq and q*qq <= 0.0 then
  60. found := if q=0.0 then caddr p!-get3(pts,i,j,k)
  61. else ploteval3impl3(caddr p!-get3(pts,i,j,k),qq,
  62. caddr p!-get3(pts,i,j,k#+1),q);
  63. if q=0.0 or qq=0.0 or not found then p!-put3(val,i,j,k,nil);
  64. done:=done or found;
  65. q:=qq;
  66. >>;
  67. {t,t,car pt,cadr pt,found}
  68. >>;
  69. if done then l:=w.l;
  70. >>;
  71. return ploteval3xy3 l;
  72. end;
  73. symbolic procedure ploteval3impl3(p1,f1,p2,f2);
  74. % linear interpolation
  75. <<
  76. fdeclare(f1,f2,p1,p2);
  77. (f1*p2 - f2*p1)/(f1-f2)>>;
  78. endmodule;
  79. end;