Here is a draft of a draw routine. It is intended to set up linked lists for draw primitives such as circles and squares. While not a working draft, it compiles and runs the little test. And the logic is readable in Pascal.
Program DrawList;
Uses DrawUnit, BresenhamAlgorithm ;
var aPixelptr : pPixel ; aPixel : TPixel ;
begin aPixel.x := 50 ; aPixel.y := 50 ; aPixel.color := 50 ;
aPixelptr := NewPixel(aPixel); Writeln ('went OK' ); end.
UNIT DrawUnit;
INTERFACE
USES BresenhamAlgorithm ;
FUNCTION NewPixel ( pixel : TPixel) : pPixel ; { Creates a New Pixel } PROCEDURE ErasePixel ( ThisPixel : pPixel ) ;
FUNCTION NewLine ( pixel1, pixel2 : TPixel ) : pListElement ; { Creates a New LinkedPixelList. } PROCEDURE EraseLine ( ThisLine : pListElement ) ;
(*=========================================================*)
IMPLEMENTATION
Function NewPixel ( pixel : TPixel ) : pPixel;
var ThisPixel : pPixel;
begin ThisPixel := New(pPixel) ; { This Pixel is a start pointer } ThisPixel^.x := pixel.x ; ThisPixel^.y := pixel.y ; ThisPixel^.color := pixel.color ; { DrawPixel( ThisPixel^ ) ;} NewPixel := ThisPixel ; end; { NewPixel }
Procedure ErasePixel( ThisPixel : pPixel ) ;
begin ThisPixel := nil ; end; { ErasePixel }
Function NewLine ( pixel1, pixel2 : TPixel ) : pListElement;
var ThisLine : pListElement ;
begin ThisLine := New(pListElement); { ThisLine is the start pointer for the Linked List } DrawLine( pixel1, pixel2, ThisLine ); NewLine := ThisLine ; end; { NewLine }
Procedure EraseLine ( ThisLine : pListElement ) ;
begin ThisLine := nil ; end;
begin end.
UNIT BresenhamAlgorithm; (* A Linked List of Pixels is created. *)
INTERFACE
TYPE pPixel = ^TPixel; TPixel = Record x, y, color : longint; end; { TPixel }
pListElement = ^PixelListElement; { The List Handle } PixelListElement = Record ListIndex : longint; Pixel : TPixel; NextPixel : pListElement; end;
PROCEDURE DrawLine( pt1, pt2 : TPixel ; pLineElement : pListElement );
(*=========================================================*)
IMPLEMENTATION
VAR i, p, dx, dy, d2x, d2y : longint ; slope: real;
PROCEDURE SwapEndPoints( var pt1, pt2 : TPixel ); Var temp : longint ;
BEGIN temp := pt2.x; pt2.x := pt1.x; pt1.x := temp;
temp := pt2.y; pt2.y := pt1.y; pt1.y := temp; END ; { SwapEndPoints }
PROCEDURE SlopeEqualsInfinity( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN
if (dy<0) then SwapEndPoints(pt1, pt2);
for i := pt1.y to pt2.y do begin pt1.y := i; pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex ); end ;
END; { SlopeEqualsInfinity }
PROCEDURE SlopeEqualsZero( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN
if (dx<0) then SwapEndPoints(pt1, pt2);
for i:=pt1.x to pt2.x do begin pt1.x := i ; pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex ); end ;
END ; { SlopeEqualsZero }
PROCEDURE SlopeZeroToOne( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN { SlopeZeroToOne }
if ( pt2.x < pt1.x ) then SwapEndPoints(pt1, pt2);
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
p := d2y - dx ; Inc( pt1.x );
while ( pt1.x < pt2.x ) do begin {while} if (p>0) then begin p := p + ( d2y - d2x ); Inc( pt1.y ); end { if }
else p := p + d2y ;
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
Inc( pt1.x );
end; {while}
END ; { SlopeZeroToOne }
PROCEDURE SlopeGreaterThanOne( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN { SlopeGreaterTanOne }
if ( pt2.y < pt1.y ) then SwapEndPoints (pt1, pt2);
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
p := d2x - dy; Inc( pt1.y );
while ( pt1.y < pt2.y ) do begin {while} if (p>0) then begin p := p + ( d2x - d2y ); Inc(pt1.x); end { if }
else p := p + d2y ;
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
Inc( pt1.y );
end; { while }
END ; { SlopeGreaterThanOne }
PROCEDURE SlopeNegOneToZero ( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN { SlopeNegOneToZero }
if ( pt2.x < pt1.x ) then SwapEndPoints (pt1, pt2);
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
p := d2y + dx; Inc( pt1.x );
while (pt1.x < pt2.x ) do begin {while} if (p>0) then begin p := p - ( d2y + d2x ); Dec(pt1.y); end { if }
else p := p - d2y;
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
Inc(pt1.x);
end; { while }
END ; { SlopeNegOneToZero }
PROCEDURE SlopeLessThanNegOne ( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN { SlopeLessThanNegOne }
if ( dy < 0 ) then SwapEndPoints ( pt1, pt2 );
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
p := d2x + dy; Inc(pt1.y);
while ( pt1.y < pt2.y ) do begin if (p>0) then begin p := p - (d2x + d2y ); Dec(pt1.x); end { if }
else p := p - d2x;
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
Inc( pt1.y );
end; { while }
END ; { SlopeLessThanNegOne }
(*=========================================================*)
PROCEDURE DrawLine( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN { DrawLine}
i := 0 ; pLineElement^.ListIndex := 0 ;
dx := pt2.x - pt1.x ; dy := pt2.y - pt1.y ; d2x := 2* dx ; d2y := 2* dy ; slope := dy /dx ;
If ( dx = 0) then SlopeEqualsInfinity( pt1, pt2, pLineElement )
else if ( dy = 0 ) then SlopeEqualsZero( pt1, pt2, pLineElement )
else if (slope > 1.0) then SlopeGreaterThanOne ( pt1, pt2, pLineElement )
else if (slope > 0.0) then SlopeZeroToOne ( pt1, pt2, pLineElement )
else if (slope < -1.0) then SlopeLessThanNegOne ( pt1, pt2, pLineElement )
else SlopeNegOneToZero ( pt1, pt2, pLineElement ) ;
END ; { DrawLine() }
(*=========================================================*) { Initialize Unit }
BEGIN
END .
{ End of Unit }