2010-11-22 5 views
0

Hallo Ich schreibe eine Anwendung mit Java. In meiner Anwendung brauche ich eine Methode, um jeden Punkt mit seinen zwei nächsten Punkten zwischen vielen verschiedenen Punkten zu verbinden (zeichne eine Linie von einem Punkt zu seinen zwei nächsten Punkten). Zuerst habe ich diese Methode, um jeden Punkt zu seinen engsten Punkt zu verbinden:verbinden Sie einen Punkt mit jedem zwei nächsten Punkt zwischen verschiedenen Punkten

public void connectingPoints() 
    { 

     ArrayList<Point> externals = new ArrayList<Point>(); 
     for(int i = 0; i<externals.size(); i++) 
     { 
      Point point = externals.get(i); 
      Point minPoint = externals.get(i+1); 
      int minXDistance = minPoint.x-point.x; 
      int minYDistance = minPoint.y-point.y; 

      for(int j = 1; j<externals.size();i++) 
      { 
       if((externals.get(j+1).x-point.x<minXDistance)&&(externals.get(j+1).y-point.y<minYDistance)) 
       { 
        minPoint = externals.get(j+1); 
       } 
      } 
      getGraphics().drawLine(point.x, point.y, minPoint.x, minPoint.y); 
      repaint(); 
     } 
    } 
} 

aber dieses nicht Methode funktioniert überhaupt nicht. Warum? Wo ist das Problem? Und wie kann ich einen Punkt mit seinem 2 nächsten Punkt verbinden.

+1

Wenn Sie sagen "funktioniert nicht", was macht es? – DJClayworth

+0

Ich verstehe die Frage nicht einmal. –

+1

Es sieht so aus, als ob Sie i erhöhen, wenn Sie j in Ihrer verschachtelten for-Schleife inkrementieren sollten. –

Antwort

1

Ich denke, Sie haben mehrere Probleme. Es sieht aus wie Sie eine Klasse wie dieses:

public class Point { 
    public double x; 
    public double y; 
} 

Sie sollten wahrscheinlich eine Methode Ihrer Klasse hinzufügen, die wie folgt aussieht:

public double distance(Point p) { 
    return Math.hypot(this.x - p.x, this.y - p.y); 
} 

Und noch eins: Jetzt

public Point getClosestPoint(List<Point> pts) { 
    double minDistSoFar = Double.MAX_VALUE; 
    Point rval = null; 

    for (Point p : pts) { 
     if (p.x == this.x && p.y == this.y) { 
      continue; 
     } 

     double pDist = this.distance(p); 
     if (pDist < minDistSoFar) { 
      minDistSoFar = pDist; 
      rval = p; 
     } 
    } 
} 

Ihr Algorithmus kann dies werden:

public void connectingPoints() 
{ 
    ArrayList<Point> externals = new ArrayList<Point>(); 
    for(Point p : externals) { 
     Point minPoint = p.getClosestPoint(externals); 
     getGraphics().drawLine(point.x, point.y, minPoint.x, minPoint.y); 
     repaint(); 
    } 
} 

EDIT: Ihr ursprüngliches Problem ist wahrscheinlich, dass Sie "i" in Ihrer Schleife indexieren, um den Wert von j zu untersuchen. Auch hier ist ein Neuschreiben mit einem einfachen (und praktikablen) Neuschreiben Ihres Codes.

public void connectingPoints() 
{ 
    ArrayList<Point> externals = new ArrayList<Point>(); 
    for(int i = 0; i<externals.size(); i++) 
    { 
     Point point = externals.get(i); 
     Point minPoint = externals.get((i+1) % externals.size()); 
     int minXDistance = minPoint.x-point.x; 
     int minYDistance = minPoint.y-point.y; 
     double minDist = Math.hypot(minXDistance, minYDistance); 

     for(int j = 0; j < externals.size(); j++) // <- you had i++ here! 
     { 
      if (i == j) { 
       continue; 
      } 

      Point testPt = externals.get(j); 
      double dist = Math.hypot(point.x - testPt.x, point.y - testPt.y); 
      if (dist < minDist) 
      { 
       minDist = dist; 
       minPoint = testPt; 
      } 
     } 
     getGraphics().drawLine(point.x, point.y, minPoint.x, minPoint.y); 
     repaint(); 
    } 
} 
+0

Guter Fang auf dem i ++ vs j ++.Habe eine Verbesserung. –

+0

danke Mark. Bin dankbar. –

2

Das ist nicht wirklich die Entfernung zwischen den Punkten zu überprüfen. Berechnen Sie den Abstand zwischen den Punkten mit dem Satz des Pythagoras und wählen Sie dann das niedrigste und das zweitniedrigste Ergebnis. Platzieren Sie den Abstand zwischen X-Werten, fügen Sie das Quadrat der Entfernung zwischen den Y-Werten hinzu, und nehmen Sie dann die Quadratwurzel.

1

Problem 1: Sie sind nicht Abstand Berechnen Sie Rechen Abstand in X + Abstand in Y.

distance = sqrt(x^2 + y^2) 

Die gute Nachricht ist, dass zu Vergleichszwecken können Sie die Quadratwurzel fallen. Sie können den Bereich "Quadrat x" und "Quadrat y" NICHT löschen. Sehr wichtig.

Problem 2: Sie finden den nächsten Punkt zweimal, nicht die nächsten zwei Punkte. Hier ist eine schnelle-n-dirty-Algorithmus, wird funktionieren, obwohl es sicherlich Raum für Verbesserungen lässt:

For each point 
    calculate and store distances to all the other points 
    // use a sorted map for the above. 
    grab the closest two points and draw your lines. 

Beachten Sie, dass dies ziemlich viel Neuberechnung verursachen, wodurch der Raum für Verbesserungen.

Beachten Sie auch, dass dies nicht einen Pfad durch alle Ihre Punkte erstellen wird.

+0

Guter Punkt auf der Quadratwurzel ist unnötig. – JOTN

+0

Ja, handlicher kleiner Trick, den ich irgendwo entlang der Linie abgeholt habe ... wahrscheinlich in einem "Game Programming Gems" -Artikel. Ich glaube nicht, dass es um die O (n^2) -Decke herum geht, obwohl Big-O nur eine Art ist, die Effizienz zu betrachten. –

+0

Das Vermeiden der Quadratwurzel ist ein großer Trick, solange Sie nicht in Überlauf geraten. Ich bin einmal in den Überlauf geraten und seitdem benutze ich die Math.hypot-Methode von Java. Aber wenn Sie wissen, dass Sie die Leistung brauchen, ist es ein wirklich praktischer Trick. –

Verwandte Themen