const
CKWW=80;
SecWW=30;
var
vs:Real;
a:Word;
begin
a:=10; //a=0~59
vs :=a/60.0*2*Pi;
with PaintBox1 do
begin
Brush.Style:=bsClear;
Pen.Width:=2; //2
Pen.Color:=clRed;
MoveTo(Round(CKWW div 2),Round(CKWW div 2));
LineTo(Round(CKWW div 2)+Round(SecWW*Sin(vs)),Round(CKWW div 2)-
Round(SecWW*Cos(vs)));
end;
end;问题:如果直线旋转到垂直或水平位置时,直线形状正常,其他位置则出现波浪或锯齿变形,如何解决?
CKWW=80;
SecWW=30;
var
vs:Real;
a:Word;
begin
a:=10; //a=0~59
vs :=a/60.0*2*Pi;
with PaintBox1 do
begin
Brush.Style:=bsClear;
Pen.Width:=2; //2
Pen.Color:=clRed;
MoveTo(Round(CKWW div 2),Round(CKWW div 2));
LineTo(Round(CKWW div 2)+Round(SecWW*Sin(vs)),Round(CKWW div 2)-
Round(SecWW*Cos(vs)));
end;
end;问题:如果直线旋转到垂直或水平位置时,直线形状正常,其他位置则出现波浪或锯齿变形,如何解决?
解决方案 »
- 关于绘图--------几个菜鸟问题请教
- 高手们,帮帮忙!!!马上结贴
- Qry2AID.Text:=Query1BID.Text; 取不到值????
- 各位大侠请进!小弟有一些常识性的问题请教!急!
- 哪位高手帮帮我!!!
- 请问哪里有聊天程序的源代码,搞过来学习一下!
- 请问谁有用Delphi开发的邮件发送与接收程序.能够发送如163,sina,sohu邮件?
- 在ontimer事件里,能否结束timer本身?
- 帮我推荐一个delphi的安装制作工具
- Delphi6的Label控件的大BUG?!!
- 100分求识别数字英文的OCR源码
- 紧急求助:TBlobField的"Bitmap image is not valit"错误解决方案
This code draws an anti-aliased line on a bitmap
This means that the line is not jagged like the
lines drawn using the LineTo() function
}uses
Graphics, Windows;type
TRGBTripleArray = array[0..1000] of TRGBTriple;
PRGBTripleArray = ^TRGBTripleArray;// anti-aliased line
procedure WuLine(ABitmap : TBitmap ; Point1, Point2 : TPoint ; AColor : TColor);
var
deltax, deltay, loop, start, finish : integer;
dx, dy, dydx : single; // fractional parts
LR, LG, LB : byte;
x1, x2, y1, y2 : integer;
begin
x1 := Point1.X; y1 := Point1.Y;
x2 := Point2.X; y2 := Point2.Y;
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
procedure AlphaBlendPixel(ABitmap : TBitmap ; X, Y : integer ; R, G, B : byte ; ARatio : Real);
Var
LBack, LNew : TRGBTriple;
LMinusRatio : Real;
LScan : PRGBTripleArray;
begin
if (X < 0) or (X > ABitmap.Width - 1) or (Y < 0) or (Y > ABitmap.Height - 1) then
Exit; // clipping
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;
var
Tmp_Bitmap: TBitmap;
Pnt1, Pnt2: TPoint;
begin
Tmp_Bitmap := TBitmap.Create; Pnt1.X := 0;
Pnt1.Y := 0;
Pnt2.X := Self.Width;
Pnt2.Y := Self.Height; WuLine(Tmp_Bitmap, Pnt1, Pnt2, clBlack);
Self.Canvas.Draw(0, 0, Tmp_Bitmap);
Tmp_Bitmap.Free;end;能帮助看一下吗?
http://www.mt86.com/graphic/ui/200506/graphic_20050611140718.shtml
Uses fixed point arithmetic. Original code by: Peter Bone
http://www.geocities.com/peter_bone_uk/engine3d.html Adapted to use Scanline pointers.*)type
TRGB = record
r : byte;
g : byte;
b : byte;
end;
TRGBArray = array[0..32767] of TRGB;
pRGBArray = ^TRGBArray;procedure WuLine(Bmp: TBitmap; x1, y1, x2, y2: integer ; R, G, B : byte);
var
deltax, deltay, X, Y, start, finish : integer;
LM, LR : integer;
dxi, dyi, dydxi : integer; W, H : integer;
ScanLines : pRGBArray;
ScanLine0,
ScanlinePtr : PByte;
ScanlineIncrement : integer;
begin
Bmp.PixelFormat := pf24bit;
W := Bmp.Width;
H := Bmp.Height; deltax := abs(x2 - x1); // Calculate deltax and deltay for initialisation
deltay := abs(y2 - y1); if (deltax = 0) or (deltay = 0) then begin
Bmp.Canvas.Pen.Color := (B shl 16) + (G shl 8) + R;
Bmp.Canvas.MoveTo(x1, y1);
Bmp.Canvas.LineTo(x2, y2); exit;
end; //use pointers instead of scanline (faster than accessing scanline)
ScanLine0 := Bmp.Scanline[0];
ScanlinePtr := Bmp.Scanline[0];
ScanlineIncrement := integer(Bmp.Scanline[1]) - integer(ScanlinePtr); if deltax > deltay then begin // horizontal or vertical
if y2 > y1 then // determine rise and run
dydxi := -deltay shl 16 div deltax
else
dydxi := deltay shl 16 div deltax; if x2 < x1 then begin
start := x2; // right to left
finish := x1;
dyi := y2 shl 16;
end else begin
start := x1; // left to right
finish := x2;
dyi := y1 shl 16;
dydxi := -dydxi; // inverse slope
end; if finish >= W then
finish := W - 1; for X := start to finish do begin
Y := dyi shr 16;
if (X < 0) or (Y < 0) or (Y > H-2) then begin
Inc(dyi, dydxi);
Continue;
end; LM := dyi - Y shl 16; // fractional part of dyi - in fixed-point
LR := 65536 - LM; ScanlinePtr := ScanLine0;
Inc(ScanlinePtr, ScanlineIncrement *Y);
ScanLines := pRGBArray(ScanLinePtr); Scanlines[X].B := (B*LR + Scanlines[X].B*LM) shr 16;
Scanlines[X].G := (G*LR + Scanlines[X].G*LM) shr 16;
Scanlines[X].R := (R*LR + Scanlines[X].R*LM) shr 16; Inc(ScanlinePtr, ScanlineIncrement);
ScanLines := pRGBArray(ScanLinePtr); Scanlines[X].B := (B*LM + Scanlines[X].B*LR) shr 16;
Scanlines[X].G := (G*LM + Scanlines[X].G*LR) shr 16;
Scanlines[X].R := (R*LM + Scanlines[X].R*LR) shr 16; Inc(dyi, dydxi); // next point
end;
end else begin
if x2 > x1 then // determine rise and run
dydxi := -deltax shl 16 div deltay
else
dydxi := deltax shl 16 div deltay; if y2 < y1 then begin
start := y2; // right to left
finish := y1;
dxi := x2 shl 16;
end else begin
start := y1; // left to right
finish := y2;
dxi := x1 shl 16;
dydxi := -dydxi; // inverse slope
end; if finish >= H then
finish := H - 1; for Y := start to finish do begin
X := dxi shr 16; if (Y < 0) or (X < 0) or (X > W-2) then begin
Inc(dxi, dydxi);
Continue;
end; LM := dxi - X shl 16;
LR := 65536 - LM; ScanlinePtr := ScanLine0;
Inc(ScanlinePtr, ScanlineIncrement *Y);
ScanLines := pRGBArray(ScanLinePtr); Scanlines[X].B := (B*LR + Scanlines[X].B*LM) shr 16;
Scanlines[X].G := (G*LR + Scanlines[X].G*LM) shr 16;
Scanlines[X].R := (R*LR + Scanlines[X].R*LM) shr 16; Inc(X); Scanlines[X].B := (B*LM + Scanlines[X].B*LR) shr 16;
Scanlines[X].G := (G*LM + Scanlines[X].G*LR) shr 16;
Scanlines[X].R := (R*LM + Scanlines[X].R*LR) shr 16; Inc(dxi, dydxi); // next point
end;
end;
end;
Just to confuse things, here's another version that is slightly slower
but draws better lines. This gives the same result as drawing the same
line twice (one on top of the other) which reduces the effect of
alternating light and dark patches.
*)
procedure WuLine2(Bmp: TBitmap; x1, y1, x2, y2 : integer ; R, G, B : byte);
var
deltax, deltay, X, Y, start, finish : integer;
LM, LR, LMR, LMM, LRR : integer;
dxi, dyi, dydxi : integer; ScanLines : pRGBArray;
ScanLine0,
ScanlinePtr : PByte;
ScanlineIncrement : integer;
begin
Bmp.PixelFormat := pf24bit; deltax := abs(x2 - x1); // Calculate deltax and deltay for initialisation
deltay := abs(y2 - y1);
if (deltax = 0) or (deltay = 0) then begin
Bmp.Canvas.Pen.Color := (B shl 16) + (G shl 8) + R;
Bmp.Canvas.MoveTo(x1, y1);
Bmp.Canvas.LineTo(x2, y2);
exit;
end; //use pointers instead of scanline (faster than accessing scanline)
ScanLine0 := Bmp.Scanline[0];
ScanlinePtr := Bmp.Scanline[0];
ScanlineIncrement := integer(Bmp.Scanline[1]) - integer(ScanlinePtr); if deltax > deltay then begin // horizontal or vertical
if y2 > y1 then // determine rise and run
dydxi := -deltay shl 11 div deltax
else
dydxi := deltay shl 11 div deltax;
if x2 < x1 then begin
start := x2; // right to left
finish := x1;
dyi := y2 shl 11;
end else begin
start := x1; // left to right
finish := x2;
dyi := y1 shl 11;
dydxi := -dydxi; // inverse slope
end; if finish >= Bmp.Width then finish := Bmp.Width - 1; for X := start to finish do begin
Y := dyi shr 11;
if (X < 0) or (Y < 0) or (Y > Bmp.Height-2) then begin
Inc(dyi, dydxi);
Continue;
end;
LM := dyi - Y shl 11; // fractional part of dyi - in fixed-point
LR := 2048 - LM;
LMR := LM * LR;
LMM := LM * LM;
LRR := LR * LR; ScanlinePtr := ScanLine0;
Inc(ScanlinePtr, ScanlineIncrement *Y);
ScanLines := pRGBArray(ScanLinePtr); Scanlines[X].B := B*LR shr 11 + (B*LMR + Scanlines[X].B*LMM) shr 22;
Scanlines[X].G := G*LR shr 11 + (G*LMR + Scanlines[X].G*LMM) shr 22;
Scanlines[X].R := R*LR shr 11 + (R*LMR + Scanlines[X].R*LMM) shr 22; Inc(ScanlinePtr, ScanlineIncrement);
ScanLines := pRGBArray(ScanLinePtr); Scanlines[X].B := B*LM shr 11 + (B*LMR + Scanlines[X].B*LRR) shr 22;
Scanlines[X].G := G*LM shr 11 + (G*LMR + Scanlines[X].G*LRR) shr 22;
Scanlines[X].R := R*LM shr 11 + (R*LMR + Scanlines[X].R*LRR) shr 22;
Inc(dyi, dydxi); // next point
end;
end else begin
if x2 > x1 then // determine rise and run
dydxi := -deltax shl 11 div deltay
else
dydxi := deltax shl 11 div deltay;
if y2 < y1 then begin
start := y2; // right to left
finish := y1;
dxi := x2 shl 11;
end else begin
start := y1; // left to right
finish := y2;
dxi := x1 shl 11;
dydxi := -dydxi; // inverse slope
end;
if finish >= Bmp.Height then finish := Bmp.Height - 1;
for Y := start to finish do begin
X := dxi shr 11;
if (Y < 0) or (X < 0) or (X > Bmp.Width-2) then begin
Inc(dxi, dydxi);
Continue;
end;
LM := dxi - X shl 11;
LR := 2048 - LM;
LMR := LM * LR;
LMM := LM * LM;
LRR := LR * LR; ScanlinePtr := ScanLine0;
Inc(ScanlinePtr, ScanlineIncrement *Y);
ScanLines := pRGBArray(ScanLinePtr); Scanlines[X].B := B*LR shr 11 + (B*LMR + Scanlines[X].B*LMM) shr 22;
Scanlines[X].G := G*LR shr 11 + (G*LMR + Scanlines[X].G*LMM) shr 22;
Scanlines[X].R := R*LR shr 11 + (R*LMR + Scanlines[X].R*LMM) shr 22;
Inc(X);
Scanlines[X].B := B*LM shr 11 + (B*LMR + Scanlines[X].B*LRR) shr 22;
Scanlines[X].G := G*LM shr 11 + (G*LMR + Scanlines[X].G*LRR) shr 22;
Scanlines[X].R := R*LM shr 11 + (R*LMR + Scanlines[X].R*LRR) shr 22;
Inc(dxi, dydxi); // next point
end;
end;
end;
var
Tmp_Bitmap: TBitmap;
Pnt1, Pnt2: TPoint;
begin
Tmp_Bitmap := TBitmap.Create;
Tmp_Bitmap.Width:=200;
Tmp_Bitmap.Height:=200;
Pnt1.X := 0;
Pnt1.Y := 0;
Pnt2.X := Self.Width;
Pnt2.Y := Self.Height; WuLine(Tmp_Bitmap, Pnt1, Pnt2, clBlack);
Self.Canvas.Draw(0, 0, Tmp_Bitmap);
Tmp_Bitmap.Free;end;
fgraphics.SetSmoothingMode(SmoothingModeAntiAlias);
///
GDI+ Delphi 开发包下载
http://www.2ccc.com/article.asp?articleid=3131