2017-08-13 2 views
2

Der folgende Teil des Java-Codes ist eine Lösung, um zu bestimmen, ob ein 2D-Punkt innerhalb eines Polygons liegt oder nicht (aus here). Ich denke, dieser Code hat einige Probleme. Zum Beispiel für dieses Polygon:Punkt in einem 2D-Polygon

Point[] polygon = new Point[5]; 
polygon[0] = new Point(30,20); 
polygon[1] = new Point(80,10); 
polygon[2] = new Point(75,100); 
polygon[3] = new Point(40,100); 
polygon[4] = new Point(55,65); 

Es true zurück (innen) für (76,82), aber dieser Punkt ist auf dem Rand (-Code false zurück richtig für einen anderen Punkt auf der Kante (45,17)) . Auch gibt es falsch (nicht innerhalb) für (45,90) zurück, aber es ist innerhalb des Polygons. Was ist das Problem?

public boolean IsPointInPolygon(Point p, Point[] polygon) 
{ 
    double minX = polygon[0].x; 
    double maxX = polygon[0].x; 
    double minY = polygon[0].y; 
    double maxY = polygon[0].y; 
    for (int i = 1 ; i < polygon.length; i++) 
    { 
     Point q = polygon[i]; 
     minX = Math.min(q.x, minX); 
     maxX = Math.max(q.x, maxX); 
     minY = Math.min(q.y, minY); 
     maxY = Math.max(q.y, maxY); 
    } 

    if (p.x <= minX || p.x >= maxX || p.y <= minY || p.y >= maxY) 
    { 
     return false; 
    } 

    boolean inside = false; 
    int j = polygon.length - 1; 
    for (int i = 0 ;i < polygon.length ; j = i++) 
    { 
     if ((polygon[i].y > p.y) != (polygon[j].y > p.y) && 
       p.x <= (polygon[j].x - polygon[i].x) * (p.y - polygon[i].y)/(polygon[j].y - polygon[i].y) + polygon[i].x) 
     { 
      inside = !inside; 
     } 
    } 
    return inside; 
} 

Ich glaube, ich sollte meinen Code unten ändern, aber ich bin mir nicht sicher!

float tempX = ((float)((polygon[i].x - polygon[j].x) * (p.y - polygon[i].y))/(polygon[i].y - polygon[j].y)) + polygon[i].x; 
if (p.x < tempX) { 
    inside = !inside; 
} 
else if (p.x == tempX) { 
    return false; 
} 
+0

Ich schlage vor, Sie verwenden einen Debugger und Schritt Zeile für Zeile, bis Sie die Operation finden, die nicht tut, was Sie denken, dass es sollte. – user1803551

+0

(1) Der Autor der verknüpften Seite schreibt, dass für Kantenpunkte das Ergebnis entweder wahr oder falsch ist. Daher ist das Verhalten für Ihre ersten beiden Testfälle zu erwarten. (2) Sie verwenden 'p.x <= ...' wobei der ursprüngliche Code '<' verwendet. (3) Haben Sie versucht, den ersten Punkt am Ende des Arrays zu wiederholen? Der Autor schreibt, dass es in Ihrem Fall optional ist, aber ich würde es trotzdem versuchen. –

+0

(2) Ich benutze p.x <= ... weil mein Code in einigen Fällen nicht funktioniert (45,17) (3) ja, ich wiederhole es. – hamed

Antwort

0

Dieser Algorithmus

if (p.x <= minX || p.x >= maxX || p.y <= minY || p.y >= maxY) 
{ 
     return false; 
} 

ist falsch. Es wird nur überprüft, ob der Punkt innerhalb eines durch minX, maxX, minY, maxY begrenzten Rechtecks ​​liegt. Sie können nicht testen, ob ein Punkt innerhalb eines Polygons liegt, ohne alle Polygonscheitelpunkte zu verwenden.

Verwendung java.awt.Polygon:

public boolean isPointInPolygon(Point p, Point[] points) 
    { 

     Polygon polygon = new Polygon();//java.awt.Polygon 

     for(Point point : points) { 

      polygon.addPoint(point.x, point.y); 
     } 

     return polygon.contains(p); 
    } 

Testing mit

Point[] points = new Point[5]; 
    points[0] = new Point(30,20); 
    points[1] = new Point(80,10); 
    points[2] = new Point(75,100); 
    points[3] = new Point(40,100); 
    points[4] = new Point(55,65); 

    System.out.println(isPointInPolygon(new Point(76,82), points)); 

druckt falsch.

+0

Aber Sie können schnell feststellen, dass ein Punkt ** nicht ** innerhalb eines Polygons auf diese Weise ist. Wenn beispielsweise alle Scheitelpunkte des Polygons "x" -Koordinaten> = 0 haben und die "x" -Koordinate des Testpunkts -2 ist, dann ist sichergestellt, dass der Punkt außerhalb des Polygons liegt. – Kirby

+0

Ja, ich stimme zu .. – c0der

+0

Dieser Code gibt True für Punkte an Kanten, aber ich möchte falsch zurückgeben. – hamed

Verwandte Themen