<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=Punkt-in-Polygon-Test_nach_Jordan</id>
	<title>Punkt-in-Polygon-Test nach Jordan - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=Punkt-in-Polygon-Test_nach_Jordan"/>
	<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=Punkt-in-Polygon-Test_nach_Jordan&amp;action=history"/>
	<updated>2026-06-09T03:18:45Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Wikipedia (Deutsch) – Lokale Kopie</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki-de.moshellshocker.dns64.de/index.php?title=Punkt-in-Polygon-Test_nach_Jordan&amp;diff=2039124&amp;oldid=prev</id>
		<title>imported&gt;SigmaB: Anzahl angepasst</title>
		<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=Punkt-in-Polygon-Test_nach_Jordan&amp;diff=2039124&amp;oldid=prev"/>
		<updated>2024-11-23T17:06:01Z</updated>

		<summary type="html">&lt;p&gt;Anzahl angepasst&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Der &amp;#039;&amp;#039;&amp;#039;Punkt-in-Polygon-Test nach Jordan&amp;#039;&amp;#039;&amp;#039; prüft, ob ein bestimmter [[Punkt (Geometrie)|Punkt]] in der [[Ebene (Mathematik)|Ebene]] innerhalb, außerhalb oder an der Grenze eines [[Polygon|Polygons]] liegt.&lt;br /&gt;
&lt;br /&gt;
Nach dem [[Jordanscher Kurvensatz|Jordanschen Kurvensatz]] teilen, vereinfacht gesagt, die Ränder eines [[Polygon|Polygons]] den Datenraum in eine Innen- und eine Außenseite. Für viele Anwendungen ist es nötig, herauszufinden, ob ein Punkt innerhalb oder außerhalb eines Polygons liegt.&lt;br /&gt;
&lt;br /&gt;
== Strahl-Methode ==&lt;br /&gt;
[[Datei:RecursiveEvenPolygon.svg|mini|Die Anzahl der [[Schnittpunkt|Schnittpunkte]] für einen [[Strahl (Geometrie)|Strahl]], der von der Außenseite des [[Polygon|Polygons]] bis zu einem beliebigen [[Punkt (Geometrie)|Punkt]] verläuft.]]&lt;br /&gt;
Bei der Strahl-Methode wird von dem zu testenden [[Punkt (Geometrie)|Punkt]] ein [[Strahl (Geometrie)|Strahl]] in eine beliebige Richtung versendet. Dabei wird gezählt, wie oft der Strahl die Kanten des [[Polygon|Polygons]] schneidet. Es können drei Fälle unterschieden werden:&lt;br /&gt;
# eine gerade Anzahl von [[Schnittpunkt]]en&lt;br /&gt;
# eine ungerade Anzahl von Schnittpunkten&lt;br /&gt;
# unendlich viele Schnittpunkte&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl ungerade, liegt der Punkt innerhalb des Polygons, ist sie gerade, liegt er außerhalb. Im Fall von unendlich vielen Schnittpunkten verlief der Strahl direkt auf einer Kante. Der Test muss dann mit einem anderen Winkel wiederholt werden. Durch eine verfeinerte Betrachtung der relativen Lage des Testpunktes und der Kantenenden im [[Kollinearität|kollinearen]] Fall kann jedoch auf solch eine Wiederholung mit einem anderen Winkel verzichtet werden.&lt;br /&gt;
&lt;br /&gt;
== Pseudocode ==&lt;br /&gt;
Der folgende [[Pseudocode]]&amp;lt;ref&amp;gt;vgl.&lt;br /&gt;
{{Literatur |Autor=Jeff Erickson |Titel=The Jordan Polygon Theorem |Sammelwerk=Computational Topology |WerkErg=Vorlesungsskript |Datum=2009 |Kommentar=S. 3 – dort fehlt der Fall eines Testpunkts auf einer horizontalen Kante |Online=[http://jeffe.cs.illinois.edu/teaching/comptop/2009/notes/jordan-polygon-theorem.pdf online] |Format=PDF |KBytes=144 |Abruf=2018-02-13}}&amp;lt;/ref&amp;gt; zählt die [[Schnittpunkt|Schnittpunkte]] entlang dem horizontal nach rechts gerichteten [[Strahl (Geometrie)|Strahl]] mit besonderer Beachtung der auf dem Strahl liegenden [[Ecke|Ecken]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
Funktion:  PunktInPolygon&lt;br /&gt;
Parameter: Ecken P[1], ...,P[n] eines ebenen Polygons P, Testpunkt Q&lt;br /&gt;
Rückgabe:  +1, wenn Q innerhalb P liegt;&lt;br /&gt;
           −1, wenn Q außerhalb P liegt;&lt;br /&gt;
           0, wenn Q auf P liegt&lt;br /&gt;
  Setze P[0] = P[n] und t = −1&lt;br /&gt;
  Für i = 0, ..., n−1&lt;br /&gt;
    Setze t = t * KreuzProdTest(Q,P[i],P[i+1])&lt;br /&gt;
    Wenn t = 0&lt;br /&gt;
      Abbruch der Schleife&lt;br /&gt;
  Ergebnis: t&lt;br /&gt;
&lt;br /&gt;
Funktion:  KreuzProdTest&lt;br /&gt;
Parameter: Punkte A = (x_A,y_A), B = (x_B,y_B), C = (x_C,y_C)&lt;br /&gt;
Rückgabe:  −1, wenn der Strahl von A nach rechts die Kante [BC] schneidet (außer im unteren Endpunkt);&lt;br /&gt;
           0, wenn A auf [BC] liegt;&lt;br /&gt;
           sonst +1&lt;br /&gt;
  Wenn y_A = y_B = y_C&lt;br /&gt;
    Wenn x_B ≤ x_A ≤ x_C oder x_C ≤ x_A ≤ x_B&lt;br /&gt;
      Ergebnis: 0&lt;br /&gt;
    sonst&lt;br /&gt;
      Ergebnis: +1&lt;br /&gt;
  Wenn y_A = y_B und x_A = x_B&lt;br /&gt;
    Ergebnis: 0&lt;br /&gt;
  Wenn y_B &amp;gt; y_C&lt;br /&gt;
    Vertausche B und C&lt;br /&gt;
  Wenn y_A ≤ y_B oder y_A &amp;gt; y_C&lt;br /&gt;
    Ergebnis: +1&lt;br /&gt;
  Setze Delta = (x_B−x_A) * (y_C−y_A) − (y_B−y_A) * (x_C−x_A)&lt;br /&gt;
  Wenn Delta &amp;gt; 0&lt;br /&gt;
    Ergebnis: −1&lt;br /&gt;
  sonst wenn Delta &amp;lt; 0&lt;br /&gt;
    Ergebnis: +1&lt;br /&gt;
  sonst&lt;br /&gt;
    Ergebnis: 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hinweis&amp;#039;&amp;#039;&amp;#039;: Gemäß der Beschreibung des Rückgabewertes der [[Funktion (Programmierung)|Funktion]] &amp;lt;span style=&amp;quot;font-family:monospace;&amp;quot;&amp;gt;KreuzProdTest&amp;lt;/span&amp;gt; wird bei &amp;lt;span style=&amp;quot;font-family:monospace;&amp;quot;&amp;gt;Delta &amp;gt; 0&amp;lt;/span&amp;gt; der Wert &amp;lt;math&amp;gt;-1&amp;lt;/math&amp;gt; zurückgegeben. Wenn stattdessen das [[Vorzeichen (Zahl)|Vorzeichen]] von &amp;lt;span style=&amp;quot;font-family:monospace;&amp;quot;&amp;gt;Delta&amp;lt;/span&amp;gt; zurückgegeben wird, liefert die Funktion &amp;lt;span style=&amp;quot;font-family:monospace;&amp;quot;&amp;gt;PunktInPolygon&amp;lt;/span&amp;gt; auch das korrekte Ergebnis. In diesem Fall werden die [[Schnittpunkt|Schnittpunkte]] der Kanten mit einem von &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; nach links verlaufenden Strahl gezählt.&lt;br /&gt;
&lt;br /&gt;
== Programmierung ==&lt;br /&gt;
Das folgende Beispiel in der [[Programmiersprache]] [[C-Sharp|C#]] zeigt die Implementierung des [[Algorithmus]]. Die Punkte und die [[konvexe Hülle]] werden auf dem Hauptfenster gezeichnet. Das Programm verwendet mehrere [[Klasse (Objektorientierung)|Klassen]]. Bei der Ausführung des Programms wird die [[Methode (Programmierung)|Methode]] &amp;#039;&amp;#039;Main&amp;#039;&amp;#039; verwendet, die das Ergebnis auf der Konsole ausgibt.&amp;lt;ref&amp;gt;Stack Exchange Inc: [https://stackoverflow.com/questions/4243042/c-sharp-point-in-polygon C# Point in polygon]&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;GeeksforGeeks: [https://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/ How to check if a given point lies inside or outside a polygon?]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c#&amp;quot;&amp;gt;&lt;br /&gt;
using System;&lt;br /&gt;
using System.Drawing;&lt;br /&gt;
&lt;br /&gt;
// Diese Methode gibt true zurück, wenn der Punkt innerhalb des Polygons liegt, sonst false&lt;br /&gt;
private static bool IsInside(Point[] polygon, Point point)&lt;br /&gt;
{&lt;br /&gt;
	bool isInside = false;&lt;br /&gt;
	for (int i = 0; i &amp;lt; polygon.Length; i++) // Diese for-Schleife durchläuft alle Ecken des Polygons&lt;br /&gt;
	{&lt;br /&gt;
		int j = (i + 1) % polygon.Length; // Index der nächsten Ecke&lt;br /&gt;
		if (polygon[i].Y &amp;lt; point.Y &amp;amp;&amp;amp; polygon[j].Y &amp;gt;= point.Y || polygon[j].Y &amp;lt; point.Y &amp;amp;&amp;amp; polygon[i].Y &amp;gt;= point.Y)&lt;br /&gt;
		{&lt;br /&gt;
			if ((point.Y - polygon[i].Y) * (polygon[j].X - polygon[i].X) &amp;lt; (point.X - polygon[i].X) * (polygon[j].Y - polygon[i].Y)) // Wenn der Strahl die Kante schneidet, Rückgabewert zwischen true und false wechseln&lt;br /&gt;
			{&lt;br /&gt;
				isInside = !isInside;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return isInside;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Hauptmethode, die das Programm ausführt&lt;br /&gt;
public static void Main(String[] args)&lt;br /&gt;
{&lt;br /&gt;
	int x1 = 0, y1 = 0, x2 = 100, y2 = 100; // Setzt die Koordinaten der Eckpunkte der quadratischen Fläche&lt;br /&gt;
	Random random = new Random(); // Initialisiert den Zufallsgenerator&lt;br /&gt;
	int numberOfVertices = 10;&lt;br /&gt;
	Point[] polygon = new Point[numberOfVertices]; // Deklariert ein Array für die Ecken des Polygons&lt;br /&gt;
	for (int i = 0; i &amp;lt; numberOfVertices; i++) // Diese for-Schleife erzeugt 10 zufällige Ecken innerhalb der quadratischen Fläche&lt;br /&gt;
	{&lt;br /&gt;
		Point point = new Point();&lt;br /&gt;
		point.X = (int)(random.NextDouble() * (x2 - x1) + x1);&lt;br /&gt;
		point.Y = (int)(random.NextDouble() * (y2 - y1) + y1);&lt;br /&gt;
		polygon[i] = point; // Fügt die Ecke dem Polygon hinzu&lt;br /&gt;
	}&lt;br /&gt;
	// Erzeugt einen zufälligen Punkt innerhalb der quadratischen Fläche&lt;br /&gt;
	Point randomPoint = new Point();&lt;br /&gt;
	randomPoint.X = (int)(random.NextDouble() * (x2 - x1) + x1);&lt;br /&gt;
	randomPoint.Y = (int)(random.NextDouble() * (y2 - y1) + y1);&lt;br /&gt;
	string text = &amp;quot;Liegt der Punkt (&amp;quot; + randomPoint.X + &amp;quot;, &amp;quot; + randomPoint.Y + &amp;quot;) innerhalb des Polygons mit den Ecken &amp;quot;;&lt;br /&gt;
	for (int i = 0; i &amp;lt; numberOfVertices - 1; i++)&lt;br /&gt;
	{&lt;br /&gt;
		text += &amp;quot;(&amp;quot; + polygon[i].X + &amp;quot;, &amp;quot; + polygon[i].Y + &amp;quot;), &amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
	text += &amp;quot;(&amp;quot; + polygon[numberOfVertices - 1].X + &amp;quot;, &amp;quot; + polygon[numberOfVertices - 1].Y + &amp;quot;) ?&amp;quot;;&lt;br /&gt;
	Console.WriteLine(text); // Ausgabe der Koordinaten auf der Konsole&lt;br /&gt;
	if (IsInside(polygon, randomPoint)) // Aufruf der Methode&lt;br /&gt;
	{&lt;br /&gt;
		Console.WriteLine(&amp;quot;Ja&amp;quot;); // Ausgabe auf der Konsole&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		Console.WriteLine(&amp;quot;Nein&amp;quot;); // Ausgabe auf der Konsole&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	Console.ReadLine();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Anwendungsgebiete ==&lt;br /&gt;
Diese Methode findet vor allem in [[Geoinformationssystem|Geoinformationssystemen]] Anwendung.&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
* Günter Hake, Dietmar Grünreich, [[Liqiu Meng]]: &amp;#039;&amp;#039;Kartographie&amp;#039;&amp;#039; de Gruyter, 2001, ISBN 3-11-016404-3, S. 306ff.&lt;br /&gt;
* Norbert Bartelme: &amp;#039;&amp;#039;Geoinformatik: Modelle, Strukturen, Funktionen.&amp;#039;&amp;#039; 2005, ISBN 3-540-20254-4, S. 103.&lt;br /&gt;
&lt;br /&gt;
== Einzelnachweise ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Geoinformatik]]&lt;br /&gt;
[[Kategorie:Geoinformationssystem]]&lt;br /&gt;
[[Kategorie:Algorithmische Geometrie]]&lt;/div&gt;</summary>
		<author><name>imported&gt;SigmaB</name></author>
	</entry>
</feed>