1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| procedure DrawLine( BMP : TBitMap; xo,yo,xe,ye, epTrait : integer; CoulPen : TColor; TraceMode : tTraceMode);
var Theta,miEp,si,co,mis,mic,sinco,cosco,
ep,x,y,dx,dy,xo1,yo1,xe1,ye1,xo2,yo2,xe2,ye2,a,b,xorMin,xerMax,yorMin,yerMax,rr,d,u : Extended;
iy,ix,yoMin,yeMax,xoMin,xeMax,r,i,j,xoc,xec,yoc,yec : integer;
begin dx:=xe-xo; dy:=ye-yo;
miep:=epTrait/2; rr:=miEp; ep:=0;
if dx=0 then // Verticale
begin xo1:=xo - miep; xo2:=xo + miep; yo1:=min(yo,ye); ye1:=max(yo,ye);
for ix:=trunc(xo1) to trunc(xo2) do begin
// Embouts arrondis :
d:=abs(rr-ep); if rr>d then u:=sqrt(sqr(rr)-sqr(d)) else u:=0;
yoMin:=trunc(yo1-u); yeMax:=trunc(ye1+u);
// Tracé du segment incluant les prolongements pour embouts arrondis :
DrawSegmentBis(BMP,ix,yoMin,ix,yeMax,CoulPen,TraceMode);
ep:=ep+1;
end;
EXIT;
end;
if ye=yo then // Horizontale
begin yo1:=yo - miep; yo2:=yo + miep; xo1:=min(xo,xe); xe1:=max(xo,xe);
for iy:=trunc(yo1) to trunc(yo2) do begin
// Embouts arrondis :
d:=abs(rr-ep); if rr>d then u:=sqrt(sqr(rr)-sqr(d)) else u:=0;
xoMin:=trunc(xo1-u); xeMax:=trunc(xe1+u);
// Tracé du segment incluant les prolongements pour embouts arrondis :
DrawSegmentBis(BMP,xoMin,iy,xeMax,iy,CoulPen,TraceMode);
ep:=ep+1;
end;
EXIT;
end;
// Droites inclinées
Theta:=arcTan2(ye-yo,xe-xo); a:=tan(Theta);
si:=sin(Theta); co:=cos(Theta); mis:=miep*si; mic:=miep*co;
xo1:=xo + mis; yo1:=yo - mic; xo2:=xo - mis; yo2:=yo + mic;
xe1:=xe + mis; ye1:=ye - mic; xe2:=xe - mis; ye2:=ye + mic;
sinco:=sin(Pi/2-theta); cosco:=cos(Pi/2-theta);
dy:=abs(ye-yo); dx:=abs(xe-xo);
if dy>=dx then // "y = a.x + b" --> x:= (y - b)/a
begin yorMin:=min(yo1,ye1); yerMax:=max(yo1,ye1);
b:=ye1 - a*xe1; ep:=0; si:=abs(si);
repeat // Embouts arrondis :
d:=abs(rr-ep); if rr>d then u:=si*sqrt(sqr(rr)-sqr(d)) else u:=0;
xoc:=trunc((yorMin-u-b)/a);
xec:=trunc((yerMax+u-b)/a);
// Tracé du segment incluant les prolongements pour embouts arrondis :
DrawSegmentBis(BMP,xoc,trunc(yorMin-u),xec,trunc(yerMax+u),CoulPen,TraceMode);
if TraceMode<>tmCopy then begin
ep:=ep+1;
b:=b+1/sinco;
yorMin:=yorMin+sinco;
yerMax:=yerMax+sinco;
end else begin // si tmCopy alors passe de finition resserrée
ep:=ep+0.5;
b:=b+0.5/sinco;
yorMin:=yorMin+0.5*sinco;
yerMax:=yerMax+0.5*sinco;
end;
until (ep>=epTrait);
EXIT;
end else // dy < dx -> y = a.x + b
begin b:=yo1 - a*xo1; ep:=0; co:=abs(co);
xo2:=min(xo1,xe1); xe2:=max(xo1,xe1); xorMin:=xo2; xerMax:=xe2;
repeat // Embouts arrondis :
d:=abs(rr-ep); if rr>d then u:=co*sqrt(sqr(rr)-sqr(d)) else u:=0;
// Tracé du segment incluant les prolongements pour embouts arrondis :
yoc:=trunc(a*(xorMin-u) + b);
yec:=trunc(a*(xerMax+u) + b);
DrawSegmentBis(BMP,trunc(xorMin-u),yoc, trunc(xerMax+u),yec,CoulPen,TraceMode);
if TraceMode<>tmCopy then begin
ep:=ep+1;
b:=b+1/sinco;
xorMin:=xorMin-cosco;
xerMax:=xerMax-cosco;
end else begin // si tmCopy alors passe de finition resserrée
ep:=ep+0.5;
b:=b+0.5/sinco;
xorMin:=xorMin-0.5*cosco;
xerMax:=xerMax-0.5*cosco;
end;
until (ep>=epTrait);
end;
end; // DrawLine |
Partager