// Für die foldenden
Routinen habe ich unter anderem ein // Getestet mit D4 unter WinME // Variante 1: var
r: TRect;
function MakeRect(pts: array of TPoint): TRect;
var
i, xmin, xmax, ymin, ymax: integer;
begin
xmin := maxint;
ymin := maxint;
xmax := -maxint;
ymax := -maxint;
for i := 0 to high(pts) do begin
if pts[i].x < xmin then xmin := pts[i].x;
if pts[i].x > xmax then xmax := pts[i].x;
if pts[i].y < ymin then ymin := pts[i].y;
if pts[i].y > ymax then ymax := pts[i].y;
end;
SetRect(result, xmin, ymin, xmax, ymax);
end;
function ccw(p0, p1, p2: TPoint): integer;
var
dx1, dx2, dy1, dy2: longint;
begin
dx1 := p1.x - p0.x; dx2 := p2.x - p0.x;
dy1 := p1.y - p0.y; dy2 := p2.y - p0.y;
result := ord(dx1 * dy2 > dy1 * dx2) * 2 - 1;
end;
function Intersect(p1, p2, p3, p4: TPoint): boolean;
begin
result := (((ccw(p1, p2, p3) * ccw(p1, p2, p4)) <= 0)
and ((ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0)));
end;
function PtInPolygon(pts: array of TPoint; ptTest: TPoint): boolean;
var
i, wnumintsct: word;
pt: TPoint;
begin
wnumintsct := 0;
if not PtInRect(r, ptTest) then begin
result := false;
exit;
end;
pt := ptTest;
pt.x := r.right + 50;
for i := 0 to high(pts) - 1 do begin
if Intersect(ptTest, pt, pts[i], pts[i + 1]) then inc(wnumintsct);
end;
if Intersect(ptTest, pt, pts[high(pts)], pts[0]) then inc(wnumintsct);
result := odd(wnumintsct);
end;
var
punkte: array[0..7] of TPoint;
procedure TForm1.FormPaint(Sender: TObject);
begin
canvas.polygon(punkte);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
punkte[0] := point(100, 100);
punkte[1] := point(175, 75);
punkte[2] := point(200, 0);
punkte[3] := point(225, 75);
punkte[4] := point(300, 100);
punkte[5] := point(225, 125);
punkte[6] := point(200, 200);
punkte[7] := point(175, 125);
r := MakeRect(punkte);
label1.caption := '';
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if PtInPolygon(punkte, point(x, y)) then label1.caption := 'drin'
else label1.caption := 'draußen';
end;
// Variante
2: function PtInPoly(const Points: array of TPoint; X, Y: integer): Boolean;
var
P1, P2: ^TPoint;
i, j, h, MDiff1, MDiff2: integer;
begin
h := high(points);
result := false;
j := h;
for i := 0 to h do
begin
P1 := @Points[i];
P2 := @Points[j];
if (y < P2.y) then
begin
if (P1.y <= y) then
begin
MDiff2 := (y - P1.y) * (P2.x - P1.x);
MDiff1 := (x - P1.x) * (P2.y - P1.y);
if (MDiff2 > MDiff1) then
result := not result;
end;
end
else if (y < P1.y) then
begin
MDiff2 := (y - P1.y) * (P2.x - P1.x);
MDiff1 := (x - P1.x) * (P2.y - P1.y);
if (MDiff2 < MDiff1) then
result := not result;
end;
j := i;
end;
end;
// Variante
3: function PtInPolygon(Points: array of TPoint; ptTest: TPoint): boolean;
var
i, j: integer;
lg: integer;
begin
Result := false;
lg := length(Points);
for i := 0 to pred(lg) do begin
j := succ(i) mod lg;
if ((((Points[i].y <= ptTest.y) and (ptTest.y < Points[j].y)) or
((Points[j].y <= ptTest.y) and (ptTest.y < Points[i].y))) and
(ptTest.x < (Points[j].x - Points[i].x) * (ptTest.y - Points[i].y) /
(Points[j].y - Points[i].y) + Points[i].x)) then
Result := not Result;
end;
end;
// Falls man
nur Rechtecke/Quadrate (quasi Polygone mit 4 Ecken) var
x1, x2, y1, y2: integer;
r: TRect;
procedure TForm1.FormPaint(Sender: TObject);
begin
canvas.rectangle(x1, y1, x2, y2);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
x1 := 50;
y1 := 50;
x2 := 200;
y2 := 150;
r := rect(x1, y1, x2, y2);
label1.caption := '';
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if PtInRect(r, point(x, y)) then
label1.caption := 'drin' else label1.caption := 'draußen';
end;
|
Zugriffe seit 6.9.2001 auf Delphi-Ecke





