home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
PASCAL
/
PAS_0693
/
B-SPLINE.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-06-30
|
3KB
|
94 lines
{─ Fido Pascal Conference ────────────────────────────────────────────── PASCAL ─
Msg : 319 of 434
From : Sean Palmer 1:104/123.0 08 Jun 93 00:00
To : All
Subj : fun with B-Splines
────────────────────────────────────────────────────────────────────────────────
I was just toying around with a B-Spline curve routine I got out of an
old issue of BYTE, and thought it was pretty neat. I changed it to use
fixed point fractions instead of reals, and optimized it some...
Try it! Play with it! Tell me what you think...
I was going to make it write my name on the screen in cursive but I'm
too lazy... 8)
If anyone has seen a faster B-Spline routine, let me know.}
{by Sean Palmer}
{public domain}
var color:byte;
procedure plot(x,y:word);begin
mem[$A000:y*320+x]:=color;
end;
type
coord=record x,y:word; end;
CurveDataRec=array[0..65521 div sizeof(coord)]of coord;
function fracMul(f,f2:word):word;Inline(
$58/ {pop ax}
$5B/ {pop bx}
$F7/$E3/ {mul bx}
$89/$D0); {mov ax,dx}
function mul(f,f2:word):longint;inline(
$58/ {pop ax}
$5B/ {pop bx}
$F7/$E3); {mul bx}
const nSteps=1 shl 8; {about 8 for smoothness (dots), 4 for speed (lines)}
procedure drawBSpline(var d0:coord;nPoints:word);
const nsa=$10000 div 6; nsb=$20000 div 3;
const step=$10000 div nSteps;
var
i,xx,yy:word;
t1,t2,t3:word;
c1,c2,c3,c4:word;
d:curveDataRec absolute d0;
begin
t1:=0; color:=32+2;
for i:=0 to nPoints-4 do begin
{algorithm converted from Steve Enns' original Basic subroutine}
repeat
t2:=fracMul(t1,t1); t3:=fracMul(t2,t1);
c1:=(integer(t2-t1)div 2)+nsa-fracmul(nsa,t3);
c2:=(t3 shr 1)+nsb-t2;
c3:=((t2+t1-t3)shr 1)+nsa;
c4:=fracmul(nsa,t3);
xx:=(mul(c1,d[i].x)+mul(c2,d[i+1].x)
+mul(c3,d[i+2].x)+mul(c4,d[i+3].x))shr 16;
yy:=(mul(c1,d[i].y)+mul(c2,d[i+1].y)
+mul(c3,d[i+2].y)+mul(c4,d[i+3].y))shr 16;
plot(xx,yy);
inc(t1,step);
until t1=0; {this is why nSteps must be even power of 2}
inc(color);
end;
end;
const pts=24; {number of points} {chose this because of colors}
var c:array[-1..2+pts]of coord;
var i:integer;
begin
asm mov ax,$13; int $10; end; {init vga/mcga graphics}
randomize;
for i:=1 to pts do with c[i] do begin
{x:=i*(319 div pts);} {for precision demo}
x:=random(320); {for fun demo}
y:=random(200);
end;
{for i:=1 to pts div 2 do c[i*2+1].y:=c[i*2].y;} {fit closer}
for i:=1 to pts do with c[i] do begin color:=i+32; plot(x,y); end;
{replicate end points so curves fit to input}
c[-1]:=c[1]; c[0]:=c[1]; c[pts+1]:=c[pts]; c[pts+2]:=c[pts];
drawBSpline(c[-1],pts+4);
readln;
asm mov ax,3; int $10; end; {text mode again}
end.