[Back to PRINTING SWAG index] [Back to Main SWAG index] [Original]
{
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.
[Back to PRINTING SWAG index] [Back to Main SWAG index] [Original]