this slowpoke moves

Draw Tricolor

Unit UTriangleTricolor.pas
unit UTriangleTricolor;

interface

uses math,Types,windows,Graphics,SysUtils;

type
 TIntegerArray=array[word] of integer;
 PIntegerArray=^TIntegerArray;
 tMyPoint=record x,y,c:integer; end;
 TListeMyPoint=array[0..1] of tMyPoint;
 TByte=array[0..3] of byte;

type
 TTriangleTricolor=class(Tobject)
  private
    FSommet:array[0..4]of TMYPoint;
    bord:array of TListeMyPoint;
    fcanvas:tcanvas;
    fbitmap:tbitmap;
    FMin,FMax:integer;
    function GetSommet(n: Integer): TMyPoint;
    procedure SetSommet(n: Integer; Value: TMyPoint);
    procedure drawHlineC(p1,p2:tmypoint);
    procedure drawHlineB(p1,p2:tmypoint);
    procedure PrepareBords;
    procedure CreateBord(a,b:tmypoint;drawfirst:boolean);
  public
    property Sommet[n:integer]:TMyPoint read GetSommet write SetSommet;    property canvas:tcanvas read fcanvas write fcanvas;
    procedure DrawInCanvas(canvas:tcanvas);
    procedure DrawInBitMap(bitmap:Tbitmap);
  end;

function MyPoint(x,y,c:integer):tmypoint;

implementation

function convertcolor(c:integer):integer;
begin
 result:=rgb(tbyte(c)[2],tbyte(c)[1],tbyte(c)[0]);
end;

function calculcouleur(pos,mx,c1,c2:integer):integer;
var
 a,b:TByte;
 i:integer;
begin
 if mx=0 then mx:=1;
 a:=tbyte(c1);
 b:=tbyte(c2);
 for i:=0 to 3 do a[i]:=a[i]+pos*(b[i]-a[i]) div mx;
 result:=integer(a);
end;

function MyPoint(x,y,c:integer):tmypoint;
begin
 result.x:=x;
 result.y:=y;
 result.c:=c;
end;

procedure SwapAB(var a,b:tmypoint);
var t:tmypoint;
begin
 t:=a; a:=b; b:=t;
end;

function TTriangleTricolor.GetSommet(n: Integer): TMyPoint;
begin
 result:=Mypoint(0,0,0);
 if (n<1) or (n>3) then exit;
 result:=Fsommet[n];
end;

procedure TTriangleTricolor.SetSommet(n: Integer; Value: TMyPoint);
begin
 if (n<1) or (n>3) then exit;
 Fsommet[n]:=value;
end;

procedure TTriangleTricolor.CreateBord(a,b:tmypoint;drawfirst:boolean);
var
 dx,dy,i:integer;
 drawlast:boolean;
 x,y,c:integer;
begin
 if (a.x=b.x) and (a.y=b.y) then exit;
 if (a.y=b.y) then exit;
 drawlast:=true;
 if b.y<a.y then
  begin
   swapab(a,b);
   drawlast:=drawfirst;  
   drawfirst:=true;      
  end;
 dx:=b.x-a.x;
 dy:=b.y-a.y;
 for i:=byte(not drawfirst) to dy-byte(not drawlast) do
  begin
   x:=(a.x*dy+i*dx) div dy;     
   y:=a.y+i;                    
   c:=calculcouleur(i,dy,a.c,b.c); 
   if (y-fmin>=0) and (y<=fmax) then
    begin                       
     bord[y-fmin][1]:=bord[y-fmin][0]; 
     bord[y-fmin][0]:=mypoint(x,y,c); 
    end;
  end;
end;

function MemeCote(a,b,c:tmypoint):boolean;
begin
 result:=(sign(b.y-a.y)*sign(c.y-b.y))<=0;
end;

procedure TTriangleTricolor.drawHlineC(p1,p2:tmypoint);
var
 i,dx:integer;
begin
 if p1.x>p2.x then swapab(p1,p2);
 dx:=p2.x-p1.x;
 for i:=0 to dx do canvas.pixels[p1.x+i,p1.y]:=calculcouleur(i,dx,p1.c,p2.c);
end;

procedure TTriangleTricolor.drawHlineB(p1,p2:tmypoint);
var
 i,dx:integer;
 p:pintegerarray;
begin
 if (p1.y<0) or (p1.y>=fbitmap.Height) then exit;
 fbitmap.PixelFormat:=pf32bit;
 if p1.x>p2.x then swapab(p1,p2);
 dx:=p2.x-p1.x;
 p:=fbitmap.ScanLine[p1.y];
 for i:=0 to dx do
  if (p1.x+i>=0) and (p1.x+i<fbitmap.Width) then
   p[p1.x+i]:=convertcolor(calculcouleur(i,dx,p1.c,p2.c));
end;

procedure TTriangleTricolor.PrepareBords;
var
 i:integer;
begin
 FMax:=max(max(Fsommet[1].y,Fsommet[2].y),Fsommet[3].y);
 if FMax<0 then exit;
 FMin:=min(min(Fsommet[1].y,Fsommet[2].y),Fsommet[3].y);
 if FMin<0 then FMin:=0;
 setlength(bord,fmax-fmin+1);
 Fsommet[0]:=fsommet[3];
 Fsommet[4]:=fsommet[1];
 for i:=1 to 3 do
   CreateBord(Fsommet[i],Fsommet[i+1],MemeCote(Fsommet[i-1],Fsommet[i],Fsommet[i+1]));
end;

procedure TTriangleTricolor.DrawInCanvas(canvas:tcanvas);
var
 i:integer;
begin
 PrepareBords;
 fcanvas:=canvas;
 for i:=0 to high(bord) do drawHlineC(bord[i][0],bord[i][1]);
end;

procedure TTriangleTricolor.DrawInBitMap(bitmap:Tbitmap);
var
 i:integer;
begin
 PrepareBords;
 fbitmap:=bitmap;
 for i:=0 to high(bord) do drawHlineB(bord[i][0],bord[i][1]);
end;
end.
Unit1 :
uses UTriangleTricolor

//

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
 tri:ttriangletricolor;
 bit:tbitmap;
begin
 bit:=tbitmap.Create;
 bit.Width:=width;
 bit.Height:=height;
 tri:= ttriangletricolor.create;
 tri.Sommet[1]:=MyPoint(clientwidth div 2,0,clred);
 tri.Sommet[2]:=MyPoint(0,clientheight div 2,clyellow);
 tri.Sommet[3]:=MyPoint(x,y,clwhite);
 tri.DrawInBitMap(bit);
 tri.Sommet[1]:=MyPoint(0,clientheight div 2,clyellow);
 tri.Sommet[2]:=MyPoint(clientwidth div 2,clientheight,clgreen);
 tri.Sommet[3]:=MyPoint(x,y,clwhite);
 tri.DrawInBitMap(bit);
 tri.Sommet[1]:=MyPoint(clientwidth div 2,clientheight,clgreen);
 tri.Sommet[2]:=MyPoint(clientwidth,clientheight div 2,clblue);
 tri.Sommet[3]:=MyPoint(x,y,clwhite);
 tri.DrawInBitMap(bit);
 tri.Sommet[1]:=MyPoint(clientwidth,clientheight div 2,clblue);
 tri.Sommet[2]:=MyPoint(clientwidth div 2,0,clred);
 tri.Sommet[3]:=MyPoint(x,y,clwhite);
 tri.DrawInBitMap(bit);
 tri.Free;
 canvaS.Draw(0,0,bit);
end;

Keine Kommentare:

Kommentar veröffentlichen

Beliebte Posts

Translate