2012-03-25 7 views
2

Ich habe ein Array: int [] [] rasen = new int [980] [1280];Berechnung jedes kartesischen Punktes in einem Kreis

welche die Werte der Höhe der Blätter im Rasen speichert.

In meiner Simulation habe ich einen Roboter, der um den Rasen geht und die Klingen schneidet.

Mein Roboter hat die Form eines Kreises mit einem Durchmesser (rDurchmesser). Das Koordinatensystem ist mit Double gemacht und mein Rasen ist in Integer.

Ich habe zwei "Algorithmen" entwickelt, mit denen der Roboter den Rasen schneiden kann, aber ich bin nicht zufrieden, weil die Genauigkeit meiner Algorithmen nicht hoch genug ist und die Leistung auch nicht.

Meine Frage ist, gibt es einen Weg, dies zu tun als die Ideen, die ich bereits gedacht habe?

Oder muss ich die Implementierung meines Rasens ändern, um bessere Ergebnisse zu erzielen?

Fühlen Sie sich frei, etwas zu fragen, wenn ich nicht klar genug war. Hier

ist der Code für meine beiden Algorithmen (k steht für den Roboter), centerPosition gibt das Zentrum meines Roboters (so der Mittelpunkt des Kreises)

approach with square 
    int bottomLeftCornerX = (int) (k.getCenterPosition().getX() - simulParams.getKDiameter()/2); 
    int bottomLeftCornerY = (int) (k.getCenterPosition().getY() - simulParams.getKDiameter()/2); 

    for (int i = bottomLeftCornerX; i < bottomLeftCornerX + simulParams.getKDiameter(); i++) { 
     for (int j = bottomLeftCornerY; j < bottomLeftCornerY + simulParams.getKDiameter(); j++) { 
      ((LawnArea) lawn.getBladeHeight()).cutBladeInArea(j, i); 
     } 
    } 

Und hier der mit dem Kreis Ansatz (im Grunde ist es die circonférence formule in wikipedia ...):

for (int r = 0; r < simulParams.getKDiameter()/2; r++) { 

     for (double t = 0; t < 2 * Math.PI; t = t + 0.1) { 
      Point2D p = circumference(k.getCenterPosition().getX(), k.getCenterPosition().getY(), t, r); 
      int intX = (int) Math.ceil(p.getX()); 
      int intY = (int) Math.ceil(p.getY()); 
       ((LawnArea) lawn.getBladeHeight()).cutBladeInArea(intY, intX); 
      } 
     } 
    } 
+0

Warum nicht einfach den Mittelpunkt-Kreis-Algorithmus verwenden, sondern die Koordinaten in einem Array speichern und dann den Kreis zeilenweise füllen? – harold

Antwort

0

Zur besseren Lesbarkeit: k.x ist die x-Koordinate, k.y ist die y-Koordinate, k.r der Radius ist.

for(int y = (int)Math.max(0, Math.ceil(k.y - k.r)); y <= (int)Math.min(980, Math.floor(k.y + k.r)); y++) { 
    doulbe dx = Math.sqrt(k.r * k.r - Math.abs(y-k.y) * Math.abs(y-k.y)); 
    for(int x = Math.max(0, (int)Math.ceil(k.x - dx)); x <= (int)Math.min(1280, Math.floor(k.x + dx)); x++) { 
     cut(x,y); 
    } 
}

Es gibt zwei Schleifen:
Die erste ist für die Y-Koordinate und beginnt bei k.y - k.r und geht bis k.y + k.r wenn der Kreis komplett auf dem Feld ist (ich weiß nicht, ob es immer war, wenn Ja dann kannst du die Ecken nicht erreichen), also von oben nach unten auf deinem Bildschirm.
Die zweite ist für die x-Koordinate. Die kleinsten und größten x werden mit Hilfe der Formel (k.x - x) ² + (k.y - y) ² = k.r² berechnet.
Damit erhalten Sie nur Punkte in Ihrem Kreis. Es ist ein wenig kleiner wegen double zu int Umwandlung.

+0

Vielen Dank für Ihre Antwort, ich habe Ihren Code versucht und es funktioniert sehr gut, aber ich habe nicht bekommen, was Sie mit der Tatsache saing, dass ich die Ecken nicht erreichen kann. – Seafire37

+0

Wenn ich die Klingen in den Punkten schneiden möchte, die ich verdopple zu einem höheren Wert, ist es mit Ihrer Formel möglich? – Seafire37

+0

Es ist nicht wirklich wichtig. Ich war mir nur nicht sicher, ob dein Roboter immer komplett auf dem Rasen ist, wenn er es verlassen kann. – IchBinKeinBaum

1

der erste Ansatz (basierend auf einem Begrenzungskasten) ist ein guter Anfang. Sie müssen jetzt nur noch eine Bedingung hinzufügen, die überprüft, ob sich jeder Punkt innerhalb der Begrenzungsbox ebenfalls im Kreis befindet.

Etwas wie:

for each (point p inside bounding-box) { 
    if (p inside circle centred at k) { 
     cutBlade(p); 
    } 
} 

Sie dies, dass (oder Spalte) des Begrenzungsrahmens, der Satz von Klingen in jeder Reihe von bemerken, die geschnitten werden müssen, verbessern können alle Nachbarn. Wenn Sie die Endpunkte dieses Bereichs berechnen, benötigen Sie keine Bedingungen.

Etwas wie:

for each (x inside bounding-box) { 
    calculate y_first; 
    calculate y_last; 
    for (y = y_first; y < y_last; y++) { 
     cutBlade(x,y); 
    } 
} 
+0

Vielen Dank für Ihre schnelle Antwort, ich werde versuchen, die zwei Dinge, die Sie vorgeschlagen, in der Zwischenzeit, wenn Sie andere Ideen haben, lassen Sie es mich wissen! – Seafire37

Verwandte Themen