// Getestet mit D4 unter XP procedure DrawEllipseQuadrant(cnv: TCanvas; x0, y0, rx, ry: integer);
var
rx2, ry2, rx4, ry4, F, Fx, Fy, x, y, yy: integer;
xx: single;
begin
rx2 := rx * rx;
ry2 := ry * ry;
rx4 := rx2 + rx2;
ry4 := ry2 + ry2;
F := Round(ry2 - rx2 * ry + 0.25 * rx);
Fx := 0;
Fy := rx4 * ry;
x := 0;
y := ry;
SetPixel(cnv.handle, x0 + x, y0 + y, cnv.pen.color);
while Fx < Fy do begin
if F >= 0 then begin
dec(y);
Fy := Fy - rx4;
F := F - Fy;
end;
inc(x);
Fx := Fx + ry4;
F := F + Fx + ry2;
SetPixel(cnv.handle, x0 + x, y0 + y, cnv.pen.color);
end;
xx := x + 0.5;
yy := pred(y);
F := Round(ry2 * xx * xx + rx2 * yy * yy - rx2 * ry2);
while y > 0 do begin
if F <= 0 then begin
inc(x);
Fx := Fx + ry4;
F := F + Fx;
end;
dec(y);
Fy := Fy - rx4;
F := F + rx2 - Fy;
SetPixel(cnv.handle, x0 + x, y0 + y, cnv.pen.color);
end;
end;
// Beispielaufruf
procedure TForm1.Button1Click(Sender: TObject);
begin
Canvas.pen.color := clRed;
DrawEllipseQuadrant(canvas, 200, 100, 80, 40);
end;
// 2. Wenn man das Zeichnen mit wechselnden Vorzeichen von x und y
// entsprechend wiederholt, erhält man eine komplette Ellipse.
// r0 und y0 bestimmen den Mittelpunkt, rx und ry die beiden Radien.
procedure DrawEllipse(cnv: TCanvas; x0, y0: integer; rx, ry: word);
var
rx2, ry2, rx4, ry4, F, Fx, Fy, x, y, yy: integer;
xx: single;
begin
rx2 := rx * rx;
ry2 := ry * ry;
rx4 := rx2 + rx2;
ry4 := ry2 + ry2;
F := Round(ry2 - rx2 * ry + 0.25 * rx);
Fx := 0;
Fy := rx4 * ry;
x := 0;
y := ry;
SetPixel(cnv.handle, x0 + x, y0 + y, cnv.pen.color);
SetPixel(cnv.handle, x0 - x, y0 - y, cnv.pen.color);
while Fx < Fy do begin
if F >= 0 then begin
dec(y);
Fy := Fy - rx4;
F := F - Fy;
end;
inc(x);
Fx := Fx + ry4;
F := F + Fx + ry2;
SetPixel(cnv.handle, x0 + x, y0 + y, cnv.pen.color);
SetPixel(cnv.handle, x0 - x, y0 + y, cnv.pen.color);
SetPixel(cnv.handle, x0 + x, y0 - y, cnv.pen.color);
SetPixel(cnv.handle, x0 - x, y0 - y, cnv.pen.color);
end;
xx := x + 0.5;
yy := pred(y);
F := Round(ry2 * xx * xx + rx2 * yy * yy - rx2 * ry2);
while y > 0 do begin
if F <= 0 then begin
inc(x);
Fx := Fx + ry4;
F := F + Fx;
end;
dec(y);
Fy := Fy - rx4;
F := F + rx2 - Fy;
SetPixel(cnv.handle, x0 + x, y0 + y, cnv.pen.color);
SetPixel(cnv.handle, x0 - x, y0 + y, cnv.pen.color);
SetPixel(cnv.handle, x0 + x, y0 - y, cnv.pen.color);
SetPixel(cnv.handle, x0 - x, y0 - y, cnv.pen.color);
end;
end;
// Beispielaufruf
procedure TForm1.Button2Click(Sender: TObject);
begin
Canvas.pen.color := clRed;
DrawEllipse(canvas, 200, 100, 80, 40);
end;
// 3. Mit erweitertem Code kann man eine gefüllte Ellipse zeichnen:
procedure DrawFilledEllipse
(cnv: TCanvas; x0, y0: integer; rx, ry: word; fill: Boolean);
var
rx2, ry2, rx4, ry4, F, Fx, Fy, x, y, yy: integer;
xx: single;
begin
rx2 := rx * rx;
ry2 := ry * ry;
rx4 := rx2 + rx2;
ry4 := ry2 + ry2;
F := Round(ry2 - rx2 * ry + 0.25 * rx);
Fx := 0;
Fy := rx4 * ry;
x := 0;
y := ry;
SetPixel(cnv.handle, x0 + x, y0 + y, cnv.pen.color);
SetPixel(cnv.handle, x0 - x, y0 - y, cnv.pen.color);
while Fx < Fy do begin
if F >= 0 then begin
dec(y);
Fy := Fy - rx4;
F := F - Fy;
end;
inc(x);
Fx := Fx + ry4;
F := F + Fx + ry2;
SetPixel(cnv.handle, x0 + x, y0 + y, cnv.pen.color);
SetPixel(cnv.handle, x0 - x, y0 + y, cnv.pen.color);
SetPixel(cnv.handle, x0 + x, y0 - y, cnv.pen.color);
SetPixel(cnv.handle, x0 - x, y0 - y, cnv.pen.color);
end;
xx := x + 0.5;
yy := pred(y);
F := Round(ry2 * xx * xx + rx2 * yy * yy - rx2 * ry2);
while y > 0 do begin
if F <= 0 then begin
inc(x);
Fx := Fx + ry4;
F := F + Fx;
end;
dec(y);
Fy := Fy - rx4;
F := F + rx2 - Fy;
SetPixel(cnv.handle, x0 + x, y0 + y, cnv.pen.color);
SetPixel(cnv.handle, x0 - x, y0 + y, cnv.pen.color);
SetPixel(cnv.handle, x0 + x, y0 - y, cnv.pen.color);
SetPixel(cnv.handle, x0 - x, y0 - y, cnv.pen.color);
end;
if fill then
ExtFloodfill(cnv.handle, x0, y0, cnv.pen.color, FLOODFILLBORDER);
end;
// Beispielaufruf
procedure TForm1.Button3Click(Sender: TObject);
begin
Canvas.pen.color := clRed;
Canvas.brush.color := clBlack;
DrawFilledEllipse(canvas, 200, 100, 80, 40, true);
end;
// 4. Variante 3 hat einen entscheidenden Nachteil. Wenn beispielsweise
// Linien (gleicher Farbe) die Ellipse schneiden, wird diese nicht
// vollständig gefüllt.
//
6.
Das Einfachste ist natürlich das übliche Zeichnen der Ellipse, procedure TForm1.Button7Click(Sender: TObject);
var x: integer;
begin
Canvas.pen.color := clnavy;
Canvas.brush.Style := bsClear;
for x := 0 to 60 do begin
DrawEllipseFR(canvas, 100 - x, 60, 100 + x, 150, False);
Canvas.Ellipse(230 - x, 60, 230 + x, 150);
end;
end;
// Warum aber eine
Ellipse von Hand konstruieren, wenn Delphi das ganz von |
||||
Zugriffe seit 6.9.2001 auf Delphi-Ecke





