首页  编辑  

抗锯齿的划线函数

Tags: /超级猛料/Picture.图形图像编程/控件和绘图/   Date Created:

抗锯齿的划线函数

type

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

 PRGBTripleArray = ^ TRGBTripleArray ;

// 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 ;

// 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 ;