home *** CD-ROM | disk | FTP | other *** search
- program plot_surface ;
- const numlines = 80 ; { 7-dot strips }
- pw = 199 ; { 0..pw }
- pl = 319 ; { 0..pl }
- xscmin = 0 ; xscmax = pl ;
- yscmin = 0 ; yscmax = pw ;
- c256 = 256 ;
- c255 = 255 ;
- pi = 3.1415926 ;
- type halflin = array[0..c255] of char ;
- pair = record x,y : real end ;
- triple = record x,y,z : real end ;
- intpair = record x,y : integer end;
- var
- ch : char ;
- k : integer ;
- colorX,colorY,colorB,colorBack,colorAx,xlast,ylast,ngrid,ncur : integer;
- scaleratio,shrink, a , b, c, d ,xl,xh,yl,yh : real ;
- DotBack : Boolean;
- xsc,ysc,xb,yb, zsc : real ; {world-to-screen scale ratios, offsets,Zscaler}
- P0,P1,IV,JV,KV,UP_V,DP : triple ;
- DPdotI,DPdotJ,DPdotK, vtheta,alpha,beta,Xctr,Yctr : real ;
- top,bot,lasttop,lastbot : array[0..pl] of integer ; {used by hidden line remover}
- function f( x,y : real ) : real ;
- var r : real;
- begin
- f := zsc * (X*X-1+2*X*COS(PI*Y))
- end; {R}
-
- function g1( x:real ) : real ;
- begin
- g1 := Yctr - beta*sqrt( 1.0 - sqr((x-Xctr)/alpha) )
- end ;
-
- function g2( x:real ) : real ;
- begin
- g2 := Yctr + beta*sqrt( 1.0 - sqr((x-Xctr)/alpha) )
- end;
-
- function h1( y:real ) : real ;
- begin
- h1 := Xctr - alpha*sqrt( 1.0 - sqr((y-Yctr)/beta) )
- end;
-
- function h2( y:real ) : real ;
- begin
- h2 := Xctr + alpha*sqrt( 1.0 - sqr((y-Yctr)/beta) )
- end;
-
- procedure pset( scrpt : intpair; color : integer ) ; { 0<=x<=pl , 0<=y<=pw }
- begin
- with scrpt do PLOT(x,y,color)
- end; {PSET}
-
- procedure visipset( x,y : integer; color : integer ) ;
- begin
- if y > lasttop[x] then begin
- PLOT(x,y,color) ; top[x] := y
- end; {IF}
- if y < lastbot[x] then begin
- PLOT(x,y,color) ; bot[x] := y
- end;
- end; {VISIPSET}
-
- procedure initvis ; { sets visibility arrays last.. before a pass }
- var x,k,l : integer ;
- begin
- k := pw+1 ; l := -1 ;
- for x:=0 to pl do begin
- lastbot[x] := k ; bot[x] := k ;
- lasttop[x] := l ; top[x] := l ;
- end; {FOR}
- end; {INITVIS}
-
- procedure movevis ;
- begin
- lastbot := bot ;
- lasttop := top
- end; {MOVEVIS}
-
- procedure line(x,y,dx,dy : integer; color : integer) ;
- { Bresenham's line-drawing algorithm }
- var
- i,dxsign,dysign,dxabs,dyabs : integer ;
- e,f,g : integer ;
- xp,yp : integer ;
- begin
- xp := x+dx ; yp := y+dy ; {check that all line on page}
- if ( 0<=x ) and ( x<=pl ) and ( 0<=y ) and ( y <= pw ) and (0<=xp) and (xp<=pl) and (0<=yp) and (yp<=pw)
- then begin {THEN}
- dxabs := abs(dx) ; dyabs := abs(dy) ;
- dxsign := 1 ; if dx<0 then dxsign := -dxsign ;
- dysign := 1 ; if dy<0 then dysign := -dysign ;
- f := 2*dxabs ; g := 2*dyabs ;
- xp := x ; yp := y ;
-
- if dxabs >= dyabs then begin
- e := 2*dyabs - dxabs ;
- for i := 0 to dxabs do begin
- visipset(xp,yp,color) ;
- if e > 0 then begin yp := yp + dysign ;
- e := e - f ; end;
- xp := xp + dxsign ;
- e := e + g ;
- end; {for}
- end {then}
- else begin
- e := 2*dxabs - dyabs ;
- for i := 0 to dyabs do begin
- visipset(xp,yp,color) ;
- if e > 0 then begin xp := xp + dxsign ;
- e := e - g ; end;
- yp := yp + dysign ;
- e := e + f ;
- end; {for}
- end; {else}
- end; {if}
- end; {line}
-
-
- procedure plot_at( scrpt:intpair; color : integer ) ;
- begin
- with scrpt do begin
- if (0<=x) and (x<=pl) and (0<=y) and (y<=pw) then visipset(x,y,color) ;
- xlast := x ; ylast := y ;
- end; {WITH}
- end; { PLOT_AT }
-
- procedure plot_to( scrpt:intpair; color : integer ) ;
- begin
- with scrpt do begin
- line(xlast,ylast,x-xlast,y-ylast,color) ;
- xlast := x ; ylast := y ;
- end; {WITH}
- end; { PLOT_TO }
-
- procedure setscale( eqscales : Boolean ; xl,xh,yl,yh : real ;
- var xsc,ysc,xb,yb : real ) ;
- { calc scale factors and offsets }
- var xscmid,yscmid,xmid,ymid : real ;
- begin
- xsc := (xscmax-xscmin)/(xh-xl) ;
- ysc := (yscmax-yscmin)/(yh-yl) ;
-
- if eqscales then begin
- if xsc > ysc then xsc := ysc
- else ysc := xsc ;
- end; {IF}
- xsc := shrink * xsc ;
- ysc := -shrink * ysc/scaleratio ;
- xmid := (xl+xh)/2 ; ymid := (yl+yh)/2 ;
- xscmid := (xscmin+xscmax)/2 ;
- yscmid := (yscmin+yscmax)/2 ;
- xb := xscmid - xmid * xsc ;
- yb := yscmid - ymid * ysc ;
- end; {SETSCALE}
-
- procedure setviewpt ; { inits P0,P1,IV,JV,KV }
- var
- vrho,vth,vph : real ;
- cth,sth,cph,sph : real ;
- viewplfactor : real ;
- begin
- viewplfactor := 0.5 ; {temp}
- write('Enter position of viewer : rho theta phi :') ; ;
- readln(vrho,vth,vph) ; writeln ;
- vtheta := vth ; { save eye theta in degrees }
-
- vth := pi*vth/180.0 ; vph := pi*vph/180.0 ;
- cth := cos(vth) ; sth := sin(vth) ;
- cph := cos(vph) ; sph := sin(vph) ;
- P0.x := vrho*cth*sph ;
- P0.y := vrho*sth*sph ;
- P0.z := vrho*cph ;
- writeln(' VIEWER IS AT (x,y,z) = ',P0.x:6:1,P0.y:6:1,P0.z:6:1 ) ;
-
- P1.x := viewplfactor*P0.x ;
- P1.y := viewplfactor*P0.y ;
- P1.z := viewplfactor*P0.z ;
-
- KV.x := -cth*sph ;
- KV.y := -sth*sph ;
- KV.z := -cph ;
-
- IV.x := -sth ;
- IV.y := cth ;
- IV.z := 0.0 ;
-
- JV.x := -cth*cph ;
- JV.y := -sth*cph ;
- JV.z := sph ;
-
- DP.x := P1.x-P0.x ; DP.y := P1.y-P0.y ; DP.z := P1.z-P0.z ;
- DPdotI := DP.x*IV.x + DP.y*IV.y + DP.z*IV.z ;
- DPdotJ := DP.x*JV.x + DP.y*JV.y + DP.z*JV.z ;
- DPdotK := DP.x*KV.x + DP.y*KV.y + DP.z*KV.z ;
-
- end; {SETVIEWPT}
-
- procedure persp( Q:triple; var PT:pair ) ;
- var
- DPQ : triple ;
- tmp, DPQdotI,DPQdotJ,DPQdotK : real ;
- begin
- DPQ.x := Q.x-P0.x ; DPQ.y := Q.y-P0.y ; DPQ.z := Q.z-P0.z ;
- DPQdotI := DPQ.x*IV.x + DPQ.y*IV.y + DPQ.z*IV.z ;
- DPQdotJ := DPQ.x*JV.x + DPQ.y*JV.y + DPQ.z*JV.z ;
- DPQdotK := DPQ.x*KV.x + DPQ.y*KV.y + DPQ.z*KV.z ;
- tmp := DPdotK/DPQdotK ;
- PT.x := tmp*DPQdotI - DPdotI ;
- PT.y := tmp*DPQdotJ - DPdotJ ;
- end; {PERSP}
-
- procedure ToScreen( pt:pair; var scrpt:intpair ); { plane-to-screen transformation }
- begin
- with scrpt do begin
- x := round( xsc*pt.x + xb ); y := round( ysc*pt.y + yb ) ;
- end; {WITH}
- end; {TOSCREEN}
-
- procedure worldline( A,B : triple ; xsc,ysc,xb,yb : real ) ;
- { draws line A to B }
- var AV,BV : pair ;
- xap,yap,xbp,ybp : integer ;
- begin
- persp(A,AV) ; persp(B,BV) ;
- xap := round(AV.x*xsc + xb) ;
- yap := round(AV.y*ysc + yb) ;
- xbp := round(BV.x*xsc + xb) ;
- ybp := round(BV.y*ysc + yb) ;
-
- DRAW(xap,yap,xbp,ybp,colorAx) ;
- end; {WORLDLINE}
-
- procedure scale( a,b,c,d : real ;
- var xl,xh,yl,yh : real );
- var
- i,j : integer ;
- w : triple ; pt : pair;
- y1,y2,curdx,dy : real ;
- begin
- curdx := (b-a)/ncur ;
- xl := 0.0 ; xh := xl ;
- yl := 0.0 ; yh := yl ;
-
- with w do begin
- x := a ;
- for i:=0 to ncur do begin
- y1 := g1(x) ; y2 := g2(x) ; dy := (y2-y1)/ncur ;
- y := y1 ;
- for j:=0 to ncur do begin
- z := f(x,y) ; persp(w,pt);
- if pt.x < xl then xl := pt.x else if pt.x > xh then xh := pt.x ;
- if pt.y < yl then yl := pt.y else if pt.y > yh then yh := pt.y ;
- y := y + dy ;
- end; {FOR}
- x := x + curdx ;
- end; {FOR}
- end; {WITH}
- end; {SCALE}
-
- procedure PlotXY;
- var
- w:triple; pt:pair; scrpt:intpair;
- x1,x2,y1,y2,dx,dy,curdx,curdy,xlo,xhi : real;
- nbetween,m,i,j,k : integer ;
- begin
- nbetween := ngrid div ncur ; m := 2*nbetween ;
- curdx := (b-a)/ncur ; curdy := (d-c)/ncur ;
- with w do begin
- x2 := b ;
- for i:=ncur downto 0 do begin
- { plot coordinate curve x=x2 }
- y1 := g1(x2) ; y2 := g2(x2) ;
- dy := (y2-y1)/ngrid ;
- if dy > 0 then begin
- y := y1 ; x := x2 ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_at(scrpt,colorX);
- if DotBack then pset(scrpt,colorBack) ;
- for j:=1 to ngrid do begin { draw coord curve x=x2 from y1 to y2 }
- y := y+dy ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_to(scrpt,colorX);
- if DotBack then pset(scrpt,colorBack);
- end; {FOR}
- movevis ; { transfer h/l info to last.. arrays }
-
- if i>0 then begin
- x1 := x2 - curdx ;
- { plot y=g2(x) from x=x2 to x=x1 }
- dx := (x2-x1)/m ;
- x := x2 ; y := g2(x) ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_at(scrpt,colorB);
- if DotBack then pset(scrpt,colorBack);
- for j:=m downto 1 do begin
- x := x-dx ; y := g2(x) ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_to(scrpt,colorB);
- if DotBack then pset(scrpt,colorBack);
- end; {FOR}
- movevis;
- { plot segments of 2nd coord curves from x2 to x1, WITHIN region }
- y := d ;
-
- for j:=ncur downto 0 do begin { draw coord curve at w.y }
- xlo := h1(y) ; if x1 > xlo then xlo := x1 ;
- xhi := h2(y) ; if x2 < xhi then xhi := x2 ;
- dx := (xhi-xlo)/nbetween ; x := xhi ;
- if dx > 0 then begin { draw coord curve at w.y, from xhi to xlo }
- z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_at(scrpt,colorY);
- if DotBack then pset(scrpt,colorBack) ;
- for k:= nbetween downto 1 do begin
- x := x-dx ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_to(scrpt,colorY);
- if DotBack then pset(scrpt,colorBack);
- end; {FOR}
- movevis ;
- end; {IF}
- y := y - curdy ;
- end; {FOR}
-
- { plot y=g1(x) from x=x2 to x=x1 }
- dx := (x2-x1)/m ;
- x := x2 ; y := g1(x) ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_at(scrpt,colorB);
- if DotBack then pset(scrpt,colorBack);
- for j:=m downto 1 do begin
- x := x-dx ; y := g1(x) ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_to(scrpt,colorB);
- if DotBack then pset(scrpt,colorBack);
- end; {FOR}
- movevis;
- end; {IF}
-
- end; {IF}
- x2 := x2 - curdx ;
- end; {FOR}
- end; {WITH}
- end; {PLOTXY}
-
- procedure PlotYX;
- var
- w:triple; pt:pair; scrpt:intpair;
- x1,x2,y1,y2,dx,dy,curdx,curdy,ylo,yhi : real;
- nbetween,m,i,j,k : integer ;
- begin
- nbetween := ngrid div ncur ; m := 2*nbetween ;
- curdx := (b-a)/ncur ; curdy := (d-c)/ncur ;
- with w do begin
- y2 := d ;
- for i:=ncur downto 0 do begin
- { plot 1 coordinate curve }
- x1 := h1(y2) ; x2 := h2(y2) ;
- dx := (x2-x1)/ngrid ;
- if dx > 0 then begin
- x := x1 ; y := y2 ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_at(scrpt,colorY);
- if DotBack then pset(scrpt,colorBack) ;
- for j:=1 to ngrid do begin { draw coord curve y=y2 from x1 to x2 }
- x := x+dx ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_to(scrpt,colorY);
- if DotBack then pset(scrpt,colorBack);
- end; {FOR}
- movevis ; { transfer h/l info to last.. arrays }
-
- if i>0 then begin
- y1 := y2 - curdy ;
-
- { plot x=h2(y) from y=y2 to y=y1 }
- dy := (y2-y1)/m ;
- y := y2 ; x := h2(y) ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_at(scrpt,colorB);
- if DotBack then pset(scrpt,colorBack);
- for j:=m downto 1 do begin
- y := y-dy ; x := h2(y) ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_to(scrpt,colorB);
- if DotBack then pset(scrpt,colorBack);
- end; {FOR}
- movevis;
-
- { plot segments of 2nd coord curves from y2 to y1, WITHIN region }
- x := b ;
- for j:=ncur downto 0 do begin { draw coord curve at w.x }
- ylo := g1(x) ; if y1 > ylo then ylo := y1 ;
- yhi := g2(x) ; if y2 < yhi then yhi := y2 ;
- dy := (yhi-ylo)/nbetween ; y := yhi ;
- if dy > 0 then begin { draw coord curve at w.x, from yhi to ylo }
- z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_at(scrpt,colorX);
- if DotBack then pset(scrpt,colorBack);
- for k:= nbetween downto 1 do begin
- y := y-dy ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_to(scrpt,colorX);
- if DotBack then pset(scrpt,colorBack);
- end; {FOR}
- movevis ;
- end; {IF}
- x := x - curdx ;
- end; {FOR}
-
- { plot x=h1(y) from y=y2 to y=y1 }
- dy := (y2-y1)/m ;
- y := y2 ; x := h1(y) ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_at(scrpt,colorB);
- if DotBack then pset(scrpt,colorBack);
- for j:=m downto 1 do begin
- y := y-dy ; x := h1(y) ; z := f(x,y) ;
- persp(w,pt); ToScreen(pt,scrpt); plot_to(scrpt,colorB);
- if DotBack then pset(scrpt,colorBack);
- end; {FOR}
- movevis;
-
- end; {IF}
-
- end; {IF}
- y2 := y2 - curdy ;
- end; {FOR}
- end; {WITH}
- end; {PLOTYX}
-
- procedure drawaxes( xsc,ysc,xb,yb : real ) ;
- const ticklen = 4 ; {length of a tick mark}
- var xlen,ylen,zlen : real ;
- origin,xaxis,yaxis,zaxis : triple ;
-
- procedure drawxtick( xpos:real ; halflen:integer ) ;
- begin
- end; {DRAWXTICK}
-
- procedure drawytick( ypos:real ; halflen:integer ) ;
- begin
- end; {DRAWYTICK}
-
- begin {DRAWAXES}
- writeln('Enter axis lengths from (0,0,0)') ;
- write(' xlen ylen zlen : ') ;
- readln(xlen,ylen,zlen) ; writeln ;
-
- origin.x := 0.0 ;
- origin.y := 0.0 ;
- origin.z := 0.0 ;
-
- xaxis.x := xlen ;
- xaxis.y := 0.0 ;
- xaxis.z := 0.0 ;
-
- yaxis.x := 0.0 ;
- yaxis.y := ylen ;
- yaxis.z := 0.0 ;
-
- zaxis.x := 0.0 ;
- zaxis.y := 0.0 ;
- zaxis.z := zlen ;
-
- initvis ;
- worldline(origin,xaxis,xsc,ysc,xb,yb) ;
- initvis ;
- worldline(origin,yaxis,xsc,ysc,xb,yb) ;
- initvis ;
- worldline(origin,zaxis,xsc,ysc,xb,yb) ;
- end; {DRAWAXES}
-
- procedure beep ;
- var c : char ;
- begin
- c := chr(7) ; {BELL}
- write(c) ;
- end; {BEEP}
-
- begin { MAIN }
- colorAx := 0 ; {TEMP} ; colorBack := 2 {RED};
- colorX := 3 {GREEN}; colorY := 3 {GREEN}; colorB := 1 {YELLOW};
- scaleratio := 1.1 ; { 66 v / 60 h }
-
- ngrid := 75;
- ncur := 15;
- shrink := 0.99 ; writeln;
- setviewpt ;
-
- ch := 'n' ; writeln;
- DotBack := ( ch = 'y' ) ;
- write('Enter semiaxes and center for domain elliptdisk: a b Xc Yc :');
- readln(alpha,beta,Xctr,Yctr); writeln;
- a := -alpha + Xctr ; b := alpha + Xctr ;
- c := -beta + Yctr ; d := beta + Yctr ;
- alpha := alpha + 0.001 ; beta := beta + 0.001 ;
- write('Enter Z-scale factor :'); readln(zsc); writeln;
- scale(a,b,c,d,xl,xh,yl,yh) ;
- setscale(true,xl,xh,yl,yh,xsc,ysc,xb,yb) ;
-
-
- GraphBackground(black); GraphColorMode; Palette(1);
-
- { drawaxes(xsc,ysc,xb,yb) ; }
- initvis ;
- if (-45.0 <= vtheta) and (vtheta < 45.0) then PlotXY
- else if (45.0 <= vtheta) and (vtheta <= 135.0) then PlotYX
- else begin writeln('This viewpoint not presently allowed.'); beep end;
-
-
- repeat until KeyPressed;
- TextMode;
- end. { MAIN }
-
-