{ 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.