Ja #3 und #9 schreiben über das gleiche Ding.
Der Kreis k mit Mittelpunkt M=(mx,my) und Radius r hat die Gleichung (x-mx)^2 + (y-my)^2 = r^2.
Alle Punkte (x,y) innerhalb von k erfüllen (x-mx)^2 + (y-my)^2 < r^2.
Wenn man prüfen will, ob ein Punkt (x,y) in der gemeinsamen Schnittfläche aller Kreise liegt muss man nur prüfen, ob die drei Ungleichungen für die drei Kreise erfüllt sind.
Alternativ zu Abstandsmessung/Kreisgleichung: Man kann hier auch mit
Regionen arbeiten. Dann muss man nix rechnen, wenn man wissen will,
ob ein Punkt (x,y) innerhalb einer Region liegt.
( Im Code unten findest du ein Beispiel für die Nutzung von
floodfill" fürs grüne Ausmalen der gemeinsamen Schnittmenge. )
Mit
CreateEllipticRgn() kann man die Menge der Punkte der jeweiligen Kreise definieren. Mittels
CombineRgn() wird die gemeinsame Schnittmenge (schnittmenge) ermittelt.
Wenn ein User an Position (x,y) aufs Formular klickt, wird mit if
PtInRegion( schnittmenge, x, y ) geprüft, ob (x,y) in der gemeinsamen Schnittmenge (schnittmenge) liegt.
Anstatt floodfill aus der
VCL fürs Ausmalen zu nutzen, kann man auch
Regionen mit einer Farbe belegen. Dies geschieht unten im Code mittels:
Delphi-Quellcode:
brush := CreateSolidBrush( $000000ff );
FillRgn( higru.canvas.Handle, schnittmenge, brush );
Delphi-Quellcode:
var higru : TBitMap;
schnittmenge : HRGN;
m : array[1..3] of TPoint;
procedure zeichne;
var r, d : integer;
ahrgn : array[1..3] of HRGN;
i : integer;
begin
r := trunc(higru.height/3+0.5);
d := trunc(2*r*sqrt(3)/3+0.5);
// Mittelpunkte der Kreise
m[1] := Point(r,2*r);
m[2] := Point(r+d,2*r);
m[3] := Point(trunc(r+d/2+0.5),r);
higru.Canvas.Brush.Style := bsClear;
higru.Canvas.Pen.Color := clBlack;
for i := 1 to 3 do
higru.Canvas.Ellipse( m[i].X-r,m[i].Y-r,m[i].X+r, m[i].Y+r );
higru.Canvas.Brush.Color := clgreen;
higru.canvas.brush.Style := bsSolid;
higru.Canvas.FloodFill( trunc((m[1].x+m[2].x+m[3].x)/3), trunc((m[1].y+m[2].y+m[3].y)/3), clBlack, fsBorder );
// Schnittmenge der drei Kreise berechnen => Region "schnittmenge"
// Die drei Kreise:
for i := 1 to 3 do
ahrgn[i] := CreateEllipticRgn( m[i].X-r,m[i].Y-r,m[i].X+r, m[i].Y+r );
// Kreis1 mit Kreis2 schneiden und in schnittmenge abspeichern
CombineRgn( schnittmenge, ahrgn[1], ahrgn[2], RGN_AND );
// Kreis3 mit schnittmenge schneiden und in schnittmenge abspeichern
CombineRgn( schnittmenge, schnittmenge, ahrgn[3], RGN_AND );
for i := 1 to 3 do
DeleteObject(ahrgn[i]);
end;
procedure TForm114.FormCreate(Sender: TObject);
begin
higru.SetSize( 500, 400 );
zeichne;
end;
procedure TForm114.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var brush : HBRUSH;
begin
if PtInRegion( schnittmenge, x, y ) then
begin
brush := CreateSolidBrush( $000000ff );
FillRgn( higru.canvas.Handle, schnittmenge, brush );
showmessage ( 'Ich gehöre zu "schnittmenge"' );
Repaint;
end;
end;
procedure TForm114.FormPaint(Sender: TObject);
begin
canvas.Draw( 0,0, higru );
end;
initialization
higru := TBitMap.Create;
schnittmenge := CreateRectRgn(0, 0, 0, 0);
finalization
DeleteObject( schnittmenge );
higru.free;
end.