uses Math
//
procedure RotatePts(var pts: array of TPoint;
origin: TPoint; radians: single);
var
i,x,y: integer;
cosAng, sinAng: single;
begin
cosAng := cos(radians);
sinAng := sin(radians);
for i := low(pts) to high(pts) do
begin
x := pts[i].X - origin.X;
y := pts[i].Y - origin.Y;
pts[i].X := round((x * cosAng) - (y * sinAng)) + origin.X;
pts[i].Y := round((x * sinAng) + (y * cosAng)) + origin.Y;
end;
end;
procedure DrawRotatedEllipse(canvas: TCanvas;
rec: TRect; degrees: integer);
const
//Magic constant = 2/3*(sqrt(2)-1)
offset: single = 0.27614237;
var
midx, midy, offx, offy: integer;
pts: array [0..12] of TPoint;
radians: single;
begin
degrees := degrees mod 360;
if degrees < 0 then inc(degrees, 360);
radians := degrees *pi / 180;
//if theres no rotation, use the standard Windows function
if radians = 0 then
canvas.Ellipse(rec)
else
begin
with rec do
begin
dec(right); dec(bottom); //empirically this seems better
midx := (right + left) div 2;
midy := (bottom + top) div 2;
offx := round((right - left) * offset);
offy := round((bottom - top) * offset);
pts[0] := Point(left, midy);
pts[1] := Point(left, midy - offy);
pts[2] := Point(midx - offx, top);
pts[3] := Point(midx, top);
pts[4] := Point(midx + offx, top);
pts[5] := Point(right, midy - offy);
pts[6] := Point(right, midy);
pts[7] := Point(right, midy + offy);
pts[8] := Point(midx + offx, bottom);
pts[9] := Point(midx, bottom);
pts[10] := Point(midx - offx, bottom);
pts[11] := Point(left, midy + offy);
pts[12] := pts[0];
//rotate all points about the ellipse center ...
RotatePts(pts, Point(midx,midy), radians);
end;
with canvas do
begin
beginPath(Handle);
canvas.PolyBezier(pts);
EndPath(Handle);
if canvas.Brush.Style = bsClear then
StrokePath(Handle) else
StrokeAndFillPath(Handle);
end;
end;
end;
Beispiel :
procedure TForm1.Button1Click(Sender: TObject);
const
rec: TRect = (left:100; top:100; right:300; bottom:200);
begin
canvas.Pen.Width := 2;
canvas.Brush.Color := clWhite;
DrawRotatedEllipse(Canvas, rec, 0);
//now overlay the same sized ellipse,
//but rotated at several angles ...
canvas.Brush.Style := bsClear;
DrawRotatedEllipse(Canvas, rec, -45);
DrawRotatedEllipse(Canvas, rec, 45);
DrawRotatedEllipse(Canvas, rec, 90);
end;
Keine Kommentare:
Kommentar veröffentlichen