Home » Tipps & Tricks » Grafik » Sonstiges » Prüfen, ob ein Punkt in einem Polygon liegt
Prüfen, ob ein Punkt in einem Polygon liegt
Bei diesem Algorithmus geht man von dem Punkt nach rechts und zählt die überquerten Kanten. Bei einer ungeraden Anzahl überquerter Kanten liegt der Punkt im Polygon.
Dabei sind folgen Fälle zu unterscheiden:
- Punkt auf einem Polygon-Punkt
- Punkt liegt auf gleicher Höhe mit einem Polygon-Punkt
Hier gibt es zwei Möglichkeiten:
Wird gezählt:
Wird nicht gezählt:
- Punkt.y liegt zwischen zwei Polygon-Punkten und die beiden Punkte liegen rechts vom Punkt3.
- Punkt.y liegt zwischen zwei Polygon Punkten und der Punkt liegt zwischen den beiden Punkten
Hier muss noch zusätzlich geprüft werden auf welcher Seite der Punkt liegt
function PointInPolygon(const APolygon: TPointArray; const TestPoint: TPoint): Boolean; function getNextPoint(const APolygon: TPointArray; const index: integer): TPoint; begin if index=High(APolygon) then result := APolygon[0] else result := APolygon[index+1]; end; function getPreviousPoint(const APolygon: TPointArray; const index: integer): TPoint; begin if index=0 then result := APolygon[High(APolygon)] else result := APolygon[index-1]; end; var i: integer; currentPolygonPoint: TPoint; nextPolygonPoint: TPoint; previousPolygonPoint: TPoint; crossLines: integer; begin crossLines:=0; result := false; for i := 0 to High(APolygon) do // check polygon vertices begin currentPolygonPoint := APolygon[i]; nextPolygonPoint := getNextPoint(APolygon,i); if (TestPoint.y=currentPolygonPoint.y) and (TestPoint.x=currentPolygonPoint.x) or //Horizontale Linie: ((TestPoint.y=currentPolygonPoint.y) and (TestPoint.y=nextPolygonPoint.y) and (TestPoint.xnextPolygonPoint.x)) or //vertikale Linie: ((TestPoint.x=currentPolygonPoint.x) and (TestPoint.x=nextPolygonPoint.x)and (TestPoint.y>currentPolygonPoint.y) and (TestPoint.y<nextPolygonPoint.y)) then begin //Fall 1 oder Punkt auf seknkrehcter oder horiuontaler Linie crossLines := 1; break; end else begin if (TestPoint.y=currentPolygonPoint.y) and (TestPoint.xTestPoint.y) and (nextPolygonPoint.y<TestPoint.y)) or ((previousPolygonPoint.yTestPoint.y)) then begin inc(crossLines); end; end else begin if ((TestPoint.y > currentPolygonPoint.y) and (TestPoint.y nextPolygonPoint.y) and (TestPoint.y < currentPolygonPoint.y)) then begin if (TestPoint.x<currentPolygonPoint.x) and (TestPoint.x= nextPolygonPoint.x) and (TestPoint.x = currentPolygonPoint.x) and (TestPoint.x < nextPolygonPoint.x)) then begin //Fall 4 if currentPolygonPoint.y = (TestPoint.x-currentPolygonPoint.x)/(TestPoint.y-currentPolygonPoint.y) then inc(crossLines); end; if currentPolygonPoint.y > nextPolygonPoint.y then begin // Punkt1 ist unten links if (nextPolygonPoint.x-currentPolygonPoint.x)/(nextPolygonPoint.y-currentPolygonPoint.y) <= (TestPoint.x-currentPolygonPoint.x)/(TestPoint.y-currentPolygonPoint.y) then inc(crossLines); end; end; end; end; end; end; if (crossLines mod 2) 0 then result := true; end;