[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]
{
SEAN PALMER
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...
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;
step = $10000 div nSteps;
Var
i, xx, yy,
t1, t2, t3,
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;
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.
[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]