plotexp3.red 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. module plotexp3; % Computing surface z=f(x,y) with regular grid.
  2. % Author: Herbert Melenk, ZIB Berlin.
  3. % A rectangular grid is encoded as list of rows.
  4. % A row is a list of points.
  5. % A point is a list {v,h,x,y,z} where
  6. % z,y are the coordinates and z is the function value.
  7. % The boolean values v ("vertical" = y direction) and
  8. % h ("horizontal" = x direction) are true,
  9. % if the connection to the neighbour point in that
  10. % direction is valid, nil if the connection is broken.
  11. symbolic procedure ploteval3xy(x,y,z);
  12. begin scalar rx,ry,rz,f,fcn;
  13. rx:=plotrange(x,
  14. reval(plot_xrange or '(!*interval!* -10 10)));
  15. ry:=plotrange(y,
  16. reval(plot_yrange or '(!*interval!* -10 10)));
  17. rz:=plotrange(z, reval(plot_zrange or nil));
  18. fcn := car reverse plotfunctions!*;
  19. if z='implicit then
  20. return ploteval2xyimpl(rx,ry,fcn,x,y);
  21. f:= if eqcar(fcn,'points) then caddr fcn else
  22. ploteval3xy1(cdar plotfunctions!*,
  23. z,if rz then car rz, if rz then cadr rz,
  24. x,car rx,cadr rx,
  25. y,car ry,cadr ry);
  26. plotdriver(plot!-3exp!-reg,x,y,z,f);
  27. end;
  28. symbolic procedure ploteval3xy1(f,z,zlo,zhi,x,xlo,xhi,y,ylo,yhi);
  29. begin scalar l,ff,r,w;
  30. % scalar x1,x2,y1,y2,xx,yy,p1,p2,p3,p4,f1,f2,f3,f4;
  31. integer nx,ny;
  32. z := nil;
  33. ff := rdwrap f;
  34. xlo:=rdwrap xlo; xhi:=rdwrap xhi;
  35. ylo:=rdwrap ylo; yhi:=rdwrap yhi;
  36. nx:=plot!-points(x); ny:=plot!-points(y);
  37. % compute the basic grid.
  38. r:=ploteval3xy1pts(f,ff,z,zlo,zhi,x,xlo,xhi,nx,y,ylo,yhi,ny);
  39. l:=cdr r;
  40. w:=car r;
  41. r:={l};
  42. % create refined environments for the bad points
  43. for each q in w do
  44. r:=cdr
  45. ploteval3xy1pts(f,ff,z,zlo,zhi,x,car q,cadr q,4,y,caddr q,
  46. cadddr q,4)
  47. .r;
  48. % % look for singularities or points of big variation
  49. return ploteval3xy3 r;
  50. end;
  51. symbolic procedure ploteval3xy1pts
  52. (f,ff,z,zlo,zhi,x,xlo,xhi,nx,y,ylo,yhi,ny);
  53. % Compute orthogonal graph over ordinary grid. Return additionally
  54. % a list of inner rectangles with singular points.
  55. begin scalar u,dx,dy,xx,yy,l,w;
  56. z := nil;
  57. dx:=float(xhi-xlo)/float(nx);
  58. dy:=float(yhi-ylo)/float(ny);
  59. l:=
  60. for j:=0:nx collect
  61. <<
  62. for i:=0:ny collect
  63. <<
  64. xx:=(xlo+i*dx); yy:=(ylo+j*dy);
  65. u:=plotevalform(ff,f,{x . xx,y . yy});
  66. if null u then % look for an isolated singularity WN
  67. u:=ploteval3xysingular(ff,f,x,xx,dx,y,yy,dy,zhi,zlo);
  68. if null u or eqcar(u,'overflow)
  69. or numberp u and
  70. (zhi and u>zhi or zlo and u<zlo) then
  71. <<u:=nil;
  72. if 0<j and j<nx and 0<i and i<ny then
  73. w:={xx-dx,xx+dx,yy-dy,yy+dy}.w;
  74. >>;
  75. {t,t,xx,yy,u}
  76. >>
  77. >>;
  78. return w.l;
  79. end;
  80. symbolic procedure ploteval3xy2 l;
  81. ploteval3xy3 {l};
  82. symbolic procedure ploteval3xy3 ll;
  83. % Decompose ll into maximal regular grids.
  84. begin scalar l,lr,c,w,y,r,nw;
  85. integer n,m;
  86. while ll do
  87. <<l:=car ll; ll:=cdr ll;
  88. % find stripe with maximal lower left rectangle.
  89. w:={car l,cadr l}; l:=cdr l;
  90. n:=min(ploteval3xybkpt(car w,0,nil), % hor. only
  91. ploteval3xybkpt(cadr w,0,t)); % hor. and vert
  92. c := t;
  93. while c and l and cdr l do
  94. <<m:=ploteval3xybkpt(cadr l,0,t);
  95. if izerop n and izerop m or n #>0 and not(n #> m) then
  96. <<l:= cdr l; w:=nconc(w,{car l})>>
  97. else c:=nil;
  98. >>;
  99. if cdr l then ll:=l . ll;
  100. % cut off subnet
  101. l:=nil; r:=nil; nw:=nil;
  102. for each row in w do
  103. <<if izerop n then row := cdr row
  104. else
  105. r:=(for i:=1:n collect <<y:=cddar row; row:=cdr row; y>>).r;
  106. if row then nw:=row.nw;
  107. >>;
  108. nw:= reversip nw;
  109. %print n;print{"streifen",length w,cddr caar w,
  110. % cddr lastcar lastcar w};
  111. %print "gut";print r;print "rest";print nw;
  112. %if yesp "kill" then rederr "schluss";
  113. if nw then ll:=nw.ll;
  114. if r and cdr r then lr:=r.lr;
  115. >>;
  116. return lr;
  117. end;
  118. symbolic procedure ploteval3xybkpt(w,n,m);
  119. % m=t: look for horizontal and vertical interrupts. Otherwise
  120. % look only for horizontal interrupts.
  121. if null w then n else
  122. if nil memq cddar w then n % undefined point
  123. else
  124. if null cadar w % x - break.
  125. or (m and null caar w) % y - break
  126. then n+1 else
  127. ploteval3xybkpt(cdr w,n#+1,m);
  128. endmodule;
  129. end;