Es gab mal Zeiten, da habe ich auch EXTREM viel Zeit investiert um eine Line zu zeichnen.
Das Clipping hat mich ne Weile beschäftigt....
Übrigens habe ich später festgestellt, dass der Bresenham Algorithus erstaunlich ähnlich aussieht,
den habe ich aber nicht abgeguckt, sondern tatsächlich selbst was entwickelt, anhand von Zeichnungen diverser Linien auf Karopapier.
Das war noch zu Zeiten der Hercules Grafikkarte
Eigentlich sollte man froh sein, dass man sich darum nicht mehr kümmern muss......
Das sah dann so aus:
Code: Alles auswählen
procedure Line(x1,y1,x2,y2:Integer);
var xdiff,ydiff,direction,nn:Integer;
begin
xdiff := x2 - x1;
if xdiff < 0 then begin
xdiff:=-xdiff;
nn:=x1; x1:=x2; x2:=nn;
nn:=y1; y1:=y2; y2:=nn;
end;
direction := +1;
ydiff := y2 - y1;
if ydiff < 0 then begin
ydiff := -ydiff;
direction := -direction
end;
if xdiff >= ydiff then begin
nn := (xdiff+1) DIV 2;
repeat
nn := nn - ydiff;
if nn < 0 then begin
nn := nn + xdiff;
y1 := y1 + direction;
end;
x1 := x1 + 1;
until x1 > x2;
end else begin
nn := (ydiff+1) DIV 2;
repeat
nn := nn - xdiff;
if nn < 0 then begin
nn := nn + ydiff;
x1 := x1 + 1;
end;
y1 := y1 + direction;
until y1 > y2;
end;
end;
Function ClipLineOnWindow(Var x1,y1,x2,y2:Integer;
WinX1,WinY1,WinX2,WinY2:Integer):Boolean;
VAR xdiff,ydiff,n,rest:Word; nn:LongInt;
temp:integer;
Begin
ClipLineOnWindow:=False;
if y1=y2 then Begin
if y1 < WinY1 then Exit;
if y1 > WinY2 then Exit;
if x1 > x2 then Begin
temp:=x1; x1:=x2; x2:=temp;
end;
if x2 < WinX1 then Exit;
if x1 > WinX2 then Exit;
if x1 < WinX1 then x1:=WinX1;
if x2 > WinX2 then x2:=WinX2;
ClipLineOnWindow:=True;
Exit;
end;
if x1=x2 then Begin
if x1 < WinX1 then Exit;
if x1 > WinX2 then Exit;
if y1 > y2 then Begin
temp:=y1; y1:=y2; y2:=temp;
end;
if y2 < WinY1 then Exit;
if y1 > WinY2 then Exit;
if y1 < WinY1 then y1:=WinY1;
if y2 > WinY2 then y2:=WinY2;
ClipLineOnWindow:=True;
Exit;
end;
if x1 > x2 then Begin
temp:=x1; x1:=x2; x2:=temp;
temp:=y1; y1:=y2; y2:=temp;
end;
if x1 > WinX2 then Exit;
if x2 < WinX1 then Exit;
{$R-}
xdiff:=x2;
xdiff:=xdiff-x1;
{$R+}
if y1 > y2 then Begin
if y1 < WinY1 then Exit;
if y2 > WinY2 then Exit;
ydiff:=y1;
ydiff:=ydiff-y2;
if xdiff >= ydiff then Begin
n:=xdiff SHR 1;
if x1 < WinX1 then Begin
nn:=WinX1;
nn:=nn-x1;
nn:=nn*ydiff;
nn:=nn+n;
n :=nn MOD xdiff;
nn:=nn DIV xdiff;
y1:=y1-nn;
if y1 < WinY1 then Exit;
x1:=WinX1;
end;
if x2 > WinX2 then Begin
nn:=WinX2;
nn:=nn-x1;
inc(nn);
nn:=nn*ydiff;
nn:=nn+n;
nn:=nn DIV xdiff;
y2:=y1-nn;
if y2 > WinY2 then Exit;
x2:=WinX2;
end;
if y1 > WinY2 then Begin
nn:=y1;
nn:=nn-WinY2;
nn:=nn*xdiff;
nn:=nn-n;
rest:=nn MOD ydiff;
nn:=nn DIV ydiff;
if rest=0 then n:=0;
if rest > 0 then begin
inc(nn);
n:=ydiff-rest;
end;
x1:=x1+nn;
if x1 > WinX2 then Exit;
y1:=WinY2;
end;
if y2 < WinY1 then Begin
nn:=y1;
nn:=nn-WinY1;
inc(nn);
nn:=nn*xdiff;
nn:=nn-n;
rest:=nn MOD ydiff;
nn:=nn DIV ydiff;
if rest=0 then dec(nn);
x2:=x1+nn;
if x2 < WinX1 then Exit;
y2:=WinY1;
end;
ClipLineOnWindow:=True;
Exit;
end;
n:=ydiff SHR 1;
if y2 < WinY1 then Begin
nn:=y1;
nn:=nn-WinY1;
inc(nn);
nn:=nn*xdiff;
nn:=nn+n;
nn:=nn DIV ydiff;
x2:=x1+nn;
if x2 < WinX1 then Exit;
y2:=WinY1;
end;
if y1 > WinY2 then Begin
nn:=y1;
nn:=nn-WinY2;
nn:=nn*xdiff;
nn:=nn+n;
n :=nn MOD ydiff;
nn:=nn DIV ydiff;
x1:=x1+nn;
if x1 > WinX2 then Exit;
y1:=WinY2;
end;
if x2 > WinX2 then Begin
nn:=WinX2;
nn:=nn-x1;
inc(nn);
nn:=nn*ydiff;
nn:=nn-n;
rest:=nn MOD xdiff;
nn:=nn DIV xdiff;
if rest=0 then dec(nn);
y2:=y1-nn;
if y2 > WinY2 then Exit;
x2:=WinX2;
end;
if x1 < WinX1 then Begin
nn:=WinX1;
nn:=nn-x1;
nn:=nn*ydiff;
nn:=nn-n;
rest:=nn MOD xdiff;
nn:=nn DIV xdiff;
if rest=0 then n:=0;
if rest > 0 then begin
inc(nn);
n:=xdiff-rest;
end;
y1:=y1-nn;
if y1 < WinY1 then Exit;
x1:=WinX1;
end;
ClipLineOnWindow:=True;
Exit;
end;
if y2 < WinY1 then Exit;
if y1 > WinY2 then Exit;
{$R-}
ydiff:=y2;
ydiff:=ydiff-y1;
{$R+}
if xdiff >= ydiff then Begin
n:=xdiff SHR 1;
if x1 < WinX1 then Begin
nn:=WinX1;
nn:=nn-x1;
nn:=nn*ydiff;
nn:=nn+n;
n :=nn mod xdiff;
nn:=nn div xdiff;
y1:=y1+nn;
if y1 > WinY2 then Exit;
x1:=WinX1;
end;
if x2 > WinX2 then Begin
nn:=WinX2;
nn:=nn-x1;
inc(nn);
nn:=nn*ydiff;
nn:=nn+n;
nn:=nn DIV xdiff;
y2:=nn;
y2:=y2+y1;
if y2 < WinY1 then Exit;
x2:=WinX2;
end;
if y2 > WinY2 then Begin
nn:=Winy2;
nn:=nn-y1;
inc(nn);
nn:=nn*xdiff;
nn:=nn-n;
rest:=nn mod ydiff;
nn:=nn div ydiff;
if rest=0 then dec(nn);
x2:=nn;
x2:=x2+x1;
if x2 < WinX1 then exit;
y2:=WinY2;
end;
if y1 < WinY1 then Begin
nn:=WinY1;
nn:=nn-y1;
nn:=nn*xdiff;
nn:=nn-n;
rest:=nn MOD ydiff;
nn:=nn div ydiff;
if rest = 0 then n:=0;
if rest > 0 then begin
inc(nn);
n:=ydiff-rest;
end;
x1:=x1+nn;
if x1 > WinX2 then Exit;
y1:=WinY1;
end;
ClipLineOnWindow:=True;
Exit;
end;
n:=ydiff SHR 1;
if y1 < WinY1 then Begin
nn:=WinY1;
nn:=nn-y1;
nn:=nn*xdiff;
nn:=nn+n;
n :=nn MOD ydiff;
nn:=nn DIV ydiff;
x1:=x1+nn;
if x1 > WinX2 then exit;
y1:=WinY1;
end;
if y2 > WinY2 then Begin
nn:=Winy2;
nn:=nn-y1;
inc(nn);
nn:=nn*xdiff;
nn:=nn+n;
nn:=nn DIV ydiff;
x2:=nn;
x2:=x2+x1;
if x2< WinX1 then exit;
y2:=WinY2;
end;
if x2 > WinX2 then Begin
nn:=WinX2;
nn:=nn-x1;
inc(nn);
nn:=nn*ydiff;
nn:=nn-n;
rest:=nn mod xdiff;
nn:=nn DIV xdiff;
if rest = 0 then dec(nn);
y2:=nn;
y2:=y2+y1;
if y2 < WinY1 then Exit;
x2:=WinX2;
end;
if x1 < WinX1 then Begin
nn:=WinX1;
nn:=nn-x1;
nn:=nn*ydiff;
nn:=nn-n;
rest:=nn MOD xdiff;
nn:=nn DIV xdiff;
if rest=0 then n:=0;
if rest > 0 then begin
inc(nn);
n:=xdiff-rest;
end;
y1:=y1+nn;
if y1>WinY2 then Exit;
x1:=WinX1;
end;
ClipLineOnWindow:=True;
end;
Function PointInLine(Px,Py,Lx1,Ly1,Lx2,Ly2:Integer):Boolean;
Begin
PointInLine:=ClipLineOnWindow(Lx1,Ly1,Lx2,Ly2,Px,Py,Px,Py);
end;