反走样直线
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Image32;
type
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
procedure AALine(x1,y1,x2,y2 : single; color: TColor32; Bitmap: TBitmap32);
implementation
{$R *.dfm}
procedure AALine(x1, y1, x2, y2: single; color: TColor32; Bitmap: TBitmap32);
function CrossFadeColor(FromColor, ToColor: TColor32; Rate: Single) : TColor32;
var
R,G,B,A: BYTE;
begin
// r := Round(RedComponent(FromColor) * Rate + RedComponent(ToColor) * (1 - Rate));
// g := Round(GreenComponent(FromColor) * Rate + GreenComponent(ToColor) * (1 - Rate));
// b := Round(BlueComponent(FromColor) * Rate + BlueComponent(ToColor) * (1 - Rate));
// a := Round(AlphaComponent(FromColor) * Rate + AlphaComponent(ToColor) * (1 - Rate));
r := RedComponent(FromColor);
g := GreenComponent(FromColor);
b := BlueComponent(FromColor);
a := Round(AlphaComponent(FromColor) * Rate);
Result := RGBA(r,g,b,a); //RGB(b,g,r);
end;
// type
// intarray = array[0..1] of integer;
// pintarray = ^intarray;
procedure hpixel(x : single; y : integer);
var
FadeRate : single;
begin
FadeRate := x - trunc(x);
with bitmap do
begin
if (x>=0) and (y>=0) and (height>y) and (width>x) then
pColor32array(bitmap.ScanLine[y])[trunc(x)] := CrossFadeColor(Color,pColor32array(bitmap.ScanLine[y])[trunc(x)],1-FadeRate);
if (trunc(x)+1>=0) and (y>=0) and (height>y) and (width>trunc(x)+1) then
pColor32array(bitmap.ScanLine[y])[trunc(x)+1]:=CrossFadeColor(Color,pColor32array(bitmap.ScanLine[y])[trunc(x)+1],FadeRate);
end;
end;
procedure vpixel(x : integer; y : single);
var
FadeRate : single;
begin
FadeRate:=y-trunc(y);
with bitmap do
begin
if (x>=0) and (trunc(y)>=0) and (height>trunc(y)) and (width>x) then
pColor32array(bitmap.ScanLine[trunc(y)])[x]:=CrossFadeColor(Color,pColor32array(bitmap.ScanLine[trunc(y)])[x],1-FadeRate);
if (x>=0) and (trunc(y)+1>=0) and (height>trunc(y)+1) and (width>x) then
pColor32array(bitmap.ScanLine[trunc(y)+1])[x]:=CrossFadeColor(Color,pColor32array(bitmap.ScanLine[trunc(y)+1])[x],FadeRate);
end;
end;
var i: integer;
ly, lx, currentx, currenty, deltax, deltay, l, skipl: single;
begin
if (x1 <> x2) or (y1 <> y2) then
begin
// bitmap.PixelFormat := pf32Bit;
// Bitmap.Clear($00000000);
currentx := x1;
currenty := y1;
lx := abs(x2 - x1);
ly := abs(y2 - y1);
if lx > ly then
begin
l := trunc(lx);
deltay := (y2-y1)/l;
if x1 > x2 then
begin
deltax := -1;
skipl := (currentx - trunc(currentx));
end
else
begin
deltax := 1;
skipl := 1- (currentx - trunc(currentx));
end;
end
else
begin
l := trunc(ly);
deltax := (x2-x1)/l;
if y1 > y2 then
begin
deltay := -1;
skipl := (currenty-trunc(currenty));
end
else
begin
deltay := 1;
skipl := 1-(currenty-trunc(currenty));
end;
end;
currentx := currentx+deltax*skipl;
currenty := currenty+deltay*skipl;{}
for i := 1 to trunc(l) do
begin
if lx > ly then
vpixel(trunc(currentx), currenty)
else
hpixel(currentx, trunc(currenty));
currentx := currentx + deltax;
currenty := currenty + deltay;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
bitmap: TBitmap32;
begin
Bitmap := TBitmap32.Create;
Bitmap.Width := 400;
Bitmap.Height := 400;
Image1.picture.Bitmap.Width := 400;
Image1.picture.Bitmap.Height := 400;
AALine(0,0, 300,100, $FFFF0000, Bitmap);
Bitmap.DrawTo(0,0,Image1.Picture.Bitmap);
Bitmap.Free;
end;
end.
|