peterbone

02-07-2003, 10:04 AM

Has anyone got any code for drawing anti-aliased lines? Preferably quickly using scanline. And I mean a proper anti-aliased line - not just drawing a line and then blurring it.

Thanks

Peter

Thanks

Peter

View Full Version : anti-aliased lines

peterbone

02-07-2003, 10:04 AM

Has anyone got any code for drawing anti-aliased lines? Preferably quickly using scanline. And I mean a proper anti-aliased line - not just drawing a line and then blurring it.

Thanks

Peter

Thanks

Peter

Alimonster

02-07-2003, 10:20 AM

Would Wu anti-aliasing do you? I know that there's an add-on somewhere at Turbo (http://turbo.gamedev.net/delphix.asp) which implements this (TurboPixels or something like that -- maybe by Michael Wilson). It's for DelphiX but shouldn't be difficult to convert to normal TBitmap. I'm pretty sure that Graphics32 (http://www.g32.org/graphics32/) has anti-aliasing (and incidentally, it's waaay faster at some things than TBitmap/TCanvas -- check the demos) too. Are the above any use to you?

peterbone

02-07-2003, 12:58 PM

Weird, that's exactly what I did! I used the Turbo Pixel code and modified it.

Here's my code.

type

TRGBTripleArray = array[0..1000] of TRGBTriple;

PRGBTripleArray = ^TRGBTripleArray;

// anti-aliased line

procedure TForm1.WuLine(ABitmap : TBitmap ; x1, y1, x2, y2 : Integer ; AColor : TColor);

var

deltax, deltay, loop, start, finish: integer;

dx, dy, dydx: single; // fractional parts

LR, LG, LB : byte;

begin

deltax := abs(x2 - x1); // Calculate deltax and deltay for initialisation

deltay := abs(y2 - y1);

if (deltax = 0) or (deltay = 0) then begin // straight lines

ABitmap.Canvas.Pen.Color := AColor;

ABitmap.Canvas.MoveTo(x1, y1);

ABitmap.Canvas.LineTo(x2, y2);

exit;

end;

LR := (AColor and $000000FF);

LG := (AColor and $0000FF00) shr 8;

LB := (AColor and $00FF0000) shr 16;

if deltax > deltay then begin // horizontal or vertical

if y2 > y1 then // determine rise and run

dydx := -(deltay / deltax)

else

dydx := deltay / deltax;

if x2 < x1 then begin

start := x2; // right to left

finish := x1;

dy := y2;

end else begin

start := x1; // left to right

finish := x2;

dy := y1;

dydx := -dydx; // inverse slope

end;

for loop := start to finish do begin

AlphaBlendPixel(ABitmap, loop, trunc(dy), LR, LG, LB, 1 - frac(dy));

AlphaBlendPixel(ABitmap, loop, trunc(dy) + 1, LR, LG, LB, frac(dy));

dy := dy + dydx; // next point

end;

end else begin

if x2 > x1 then // determine rise and run

dydx := -(deltax / deltay)

else

dydx := deltax / deltay;

if y2 < y1 then begin

start := y2; // right to left

finish := y1;

dx := x2;

end else begin

start := y1; // left to right

finish := y2;

dx := x1;

dydx := -dydx; // inverse slope

end;

for loop := start to finish do begin

AlphaBlendPixel(ABitmap, trunc(dx), loop, LR, LG, LB, 1 - frac(dx));

AlphaBlendPixel(ABitmap, trunc(dx) + 1, loop, LR, LG, LB, frac(dx));

dx := dx + dydx; // next point

end;

end;

end;

// blend a pixel with the current colour and a specified colour

procedure TForm1.AlphaBlendPixel(ABitmap : TBitmap ; X, Y : integer ; R, G, B : byte ; ARatio : Real);

Var

LBack, LNew : TRGBTriple;

LMinusRatio : Real;

LScan : PRGBTripleArray;

begin

LScan := ABitmap.Scanline[Y];

LMinusRatio := 1 - ARatio;

LBack := LScan[X];

LNew.rgbtBlue := round(B*ARatio + LBack.rgbtBlue*LMinusRatio);

LNew.rgbtGreen := round(G*ARatio + LBack.rgbtGreen*LMinusRatio);

LNew.rgbtRed := round(R*ARatio + LBack.rgbtRed*LMinusRatio);

LScan[X] := LNew;

end;

Thanks anyway

Peter

Here's my code.

type

TRGBTripleArray = array[0..1000] of TRGBTriple;

PRGBTripleArray = ^TRGBTripleArray;

// anti-aliased line

procedure TForm1.WuLine(ABitmap : TBitmap ; x1, y1, x2, y2 : Integer ; AColor : TColor);

var

deltax, deltay, loop, start, finish: integer;

dx, dy, dydx: single; // fractional parts

LR, LG, LB : byte;

begin

deltax := abs(x2 - x1); // Calculate deltax and deltay for initialisation

deltay := abs(y2 - y1);

if (deltax = 0) or (deltay = 0) then begin // straight lines

ABitmap.Canvas.Pen.Color := AColor;

ABitmap.Canvas.MoveTo(x1, y1);

ABitmap.Canvas.LineTo(x2, y2);

exit;

end;

LR := (AColor and $000000FF);

LG := (AColor and $0000FF00) shr 8;

LB := (AColor and $00FF0000) shr 16;

if deltax > deltay then begin // horizontal or vertical

if y2 > y1 then // determine rise and run

dydx := -(deltay / deltax)

else

dydx := deltay / deltax;

if x2 < x1 then begin

start := x2; // right to left

finish := x1;

dy := y2;

end else begin

start := x1; // left to right

finish := x2;

dy := y1;

dydx := -dydx; // inverse slope

end;

for loop := start to finish do begin

AlphaBlendPixel(ABitmap, loop, trunc(dy), LR, LG, LB, 1 - frac(dy));

AlphaBlendPixel(ABitmap, loop, trunc(dy) + 1, LR, LG, LB, frac(dy));

dy := dy + dydx; // next point

end;

end else begin

if x2 > x1 then // determine rise and run

dydx := -(deltax / deltay)

else

dydx := deltax / deltay;

if y2 < y1 then begin

start := y2; // right to left

finish := y1;

dx := x2;

end else begin

start := y1; // left to right

finish := y2;

dx := x1;

dydx := -dydx; // inverse slope

end;

for loop := start to finish do begin

AlphaBlendPixel(ABitmap, trunc(dx), loop, LR, LG, LB, 1 - frac(dx));

AlphaBlendPixel(ABitmap, trunc(dx) + 1, loop, LR, LG, LB, frac(dx));

dx := dx + dydx; // next point

end;

end;

end;

// blend a pixel with the current colour and a specified colour

procedure TForm1.AlphaBlendPixel(ABitmap : TBitmap ; X, Y : integer ; R, G, B : byte ; ARatio : Real);

Var

LBack, LNew : TRGBTriple;

LMinusRatio : Real;

LScan : PRGBTripleArray;

begin

LScan := ABitmap.Scanline[Y];

LMinusRatio := 1 - ARatio;

LBack := LScan[X];

LNew.rgbtBlue := round(B*ARatio + LBack.rgbtBlue*LMinusRatio);

LNew.rgbtGreen := round(G*ARatio + LBack.rgbtGreen*LMinusRatio);

LNew.rgbtRed := round(R*ARatio + LBack.rgbtRed*LMinusRatio);

LScan[X] := LNew;

end;

Thanks anyway

Peter

Alimonster

02-07-2003, 01:24 PM

I must admit that that procedure doesn't seem very optimised (lots of converting to/from floats... hmm!). Maybe this one (http://www.vclcomponents.com/search.asp?ID_CATEGORY=145&PGIX=18) is a bit better -- I had a quick look and it seems to avoid any floats (good for speed). I haven't tried it, though, since I'm at work. It should be very straightforward for you to use -- just replace the Canvas.Pixels[] lines with the equivalent scanline thing.

EDIT: antialia.zip from that page. Also, I haven't checked that it does arbitrary angles and isn't just up/down/left/right. I hate being at work!

EDIT: antialia.zip from that page. Also, I haven't checked that it does arbitrary angles and isn't just up/down/left/right. I hate being at work!

peterbone

02-07-2003, 01:43 PM

That one looks a bit weird to me. I'm not sure it's Wu. I'm happy with the one I've got - it doesn't need to be that fast because I'm just drawing it on a background bitmap so it's only drawn once and not every frame.

Peter

Peter

Powered by vBulletin® Version 4.2.5 Copyright © 2019 vBulletin Solutions Inc. All rights reserved.