{ From: randyd@alpha2.csd.uwm.edu (Randall Elton Ding) All those c/pascal flames are becoming nauseating. My kill file leaves me with about 10 articles per day now. For people like me ignoring this B.S., here is something for fun. This very elegantly plots a cycloid in 3d with hidden lines. Remember that a cycloid is what you get when you trace a single point of a circle in rolling motion. Email me if you would like the normal cartesian plotter. ------------------------------------------------------------------ (* Three Dimensional Plotter (modified for this parametric equ.) written by Randy Ding randyd@alpha2.csd.uwm.edu original December 1983 (UCSD pascal) update April 13,1991 (turbo pascal) *) } {$N+} program plotter; uses graph; const bgipath = 'e:\bp\bgi'; { !set this to your bgi directory } const displaysizex= 9.75; { inches, for width/height ratios } displaysizey= 7; { inches } maxrightscreen= 999; { !make this bigger if you have incredible graphics } type realtype= single; scrnarry= array [0..maxrightscreen] of integer; { for hidden line data } var toplim,botlim,previousx,botscreen,rightscreen: integer; colr: word; top,bot: scrnarry; alpha,beta,scale,centerx,centery,posx,negx,posy,negy,stepx,stepy: realtype; procedure hideline (x,y,x2,y2: integer); var slope,yr: realtype; procedure vline (ytop,ybot: integer); { at x with colr } var temp: integer; begin if (x>=0) and (x<=rightscreen) then begin if ytop > ybot then begin temp:= ytop; ytop:= ybot; ybot:= temp; end; if x <> previousx then begin toplim:= top [x]; botlim:= bot [x]; end; if ytop < top [x] then top [x]:= ytop; if ybot > bot [x] then bot [x]:= ybot; while ytop <= ybot do begin if (ytop < toplim) or (ytop > botlim) then putpixel (x,ytop,colr); ytop:= ytop+1; end; end; previousx:= x; end; begin yr:= y; if x <> x2 then begin slope:= (y2-y)/(x2-x); while x <> x2 do begin yr:= yr+slope; vline (y,trunc(yr)); y:= trunc(yr); if x < x2 then inc(x) else dec(x); end; end; vline (y,y2); end; procedure initline; var x:integer; begin for x:= 0 to rightscreen do begin top [x]:= botscreen+1; bot [x]:= -1; end; end; { The regular cartesian plot routine has been modified to plot this parametric equation and a slope counter has been added to make the plotting slow down near the points, helping to make them crisp. The cycloid parametric function: x=u-sin(u), y=cos(u) } procedure plot; var correction,sa,ca,sb,cb,x,y,z,rho,lou,hiu,du,u,dy,oldz: realtype; oldx,oldy,screenx,screeny,slopecounter: integer; newline: boolean; ch: char; begin correction:= scale*(displaysizey/(botscreen+1)) /(displaysizex/(rightscreen+1)); sa:= sin(alpha*pi/180); ca:= cos(alpha*pi/180); sb:= sin(beta*pi/180); cb:= cos(beta*pi/180); previousx:= -1; x:= posx; while x >= negx do begin newline:= true; y:= negy; while y <= posy do begin rho:= sqrt(sqr(x)+sqr(y)); lou:= rho-1; hiu:= rho+1; repeat { solve the parametric equation by iteration } u:= (lou+hiu)/2; du:= rho-(u-sin(u)); { u-sin(u) is an increasing function } if du>0 then lou:= u else hiu:= u; until abs(du) < 0.001; z:= 3*cos(u); { user parametric function x=u-sin(u), y=cos(u) } screenx:= trunc ((y*ca-x*sa)*correction+centerx); screeny:= trunc (centery-((y*sa+x*ca)*sb+z*cb)*scale); if newline then begin slopecounter:= 0; dy:= stepy; { make dy normal for long straight runs } end else if (z-oldz)/dy > 1.5 then begin slopecounter:= 5; dy:= stepy/10; { make dy small close to the peaks } end else if slopecounter=0 then dy:= stepy else dec(slopecounter); y:= y + dy; oldz:= z; if not newline then hideline(oldx,oldy,screenx,screeny) else newline:= false; oldx:= screenx; oldy:= screeny; end; x:= x - stepx; end; end; procedure setdefault; { with no rotation, x axis is out of the screen, y axis is to the right and z axis is up; alpha and beta make the figure rotate (pos is clockwise) within the fixed coordinate axis draw figure from screen front to back for hidden lines to work properly } begin alpha:= 30; { rotates figure clockwise about z axis } beta:= -40; { rotates figure clockwise about y axis } scale:= 10; centerx:= (rightscreen+1)/2; centery:= (botscreen+1)/2; posx:= 20; { currently set up for functions z of x,y } negx:= -posx; { change user function z above in plot procedure } posy:= 20; negy:= -posy; stepx:= 0.5; stepy:= 0.1; colr:= white; end; procedure initbgi; var errcode,grmode,grdriver: integer; begin grdriver:= detect; grmode:= 0; initgraph (grdriver,grmode,bgipath); errcode:= graphresult; if errcode <> grok then begin writeln ('Graphics error: ',grapherrormsg (errcode)); halt (1); end; end; begin initbgi; botscreen:= getmaxy; rightscreen:= getmaxx; initline; setdefault; plot; readln; closegraph; end.