Ich habe ein Raumobjekt, das durch eine Sammlung von Liniensegmenten definiert ist, für die ich die Fläche berechnen muss. Die Klassen können wie folgt beschrieben werden (in Pseudocode):
class Point {
float x;
float y;
...
float distanceFrom(Point p);
}
class Segment {
Point start;
Point end;
...
float length();
}
class Room {
List<Segment> walls;
...
float area();
}
Die Wände eines Raums können sich niemals irgendwo schneiden, sondern an den Endpunkten der Segmente. Außerdem werden alle erstellten "Teilschleifen" in einen neuen Raum aufgeteilt. Die Lösung muss nicht absolut genau sein (10% Fehlerquote sind akzeptabel) und wird auch nicht sehr oft berechnet (<1 / s).
Room
eine Liste vonPoint
s zu enthalten , und dann die Segmente zu erhalten, indem jeder Punkt miteinander verbunden und dann in einer Schleife wieder herumgeführt wird. Andernfalls ist es bei Ihrer aktuellen Konfiguration sehr östlich, falsche Werte zu erhalten (z. B. nicht geschlossener Raum, Raum mit Wand in der Mitte usw.). Dies wäre die beste Option.Room
s immer vollständig sein muss und dies möglicherweise nicht der Fall ist, wenn der Player dasRoom
s mitSegment
s erstellt. Außerdem ist eine Funktion für geschlossene Räume einfach zu definieren (durchlaufen Sie einfach dieSegment
s und stellen Sie sicher, dass sie einen Raum erstellen).Antworten:
Sie können die Schnürsenkelformel von Gauß verwenden :
Sie müssen die x-Koordinate jedes Punktes nehmen, sie mit der y-Koordinate des nächsten Punktes multiplizieren, dann die y-Koordinate des aktuellen Punktes multipliziert mit der x-Koordinate des nächsten Punktes vom Ergebnis subtrahieren und zur Gesamtfläche hinzufügen. Nachdem Sie dies für jeden Punkt getan haben, halbieren Sie die Gesamtfläche, um die tatsächliche Fläche des Polygons zu erhalten. Wenn der aktuelle Punkt der letzte ist, ist der nächste der erste.
quelle
A
wird annulliert. Je nach ZielA = |A|
kann ein benötigt werden. Bei negativer Vorwahl kann die Fläche auf einem unregelmäßigen Donut anhand der inneren und äußeren Punkteliste (eine in umgekehrter Reihenfolge) ermittelt werden.Wir könnten auch eine Monte-Carlo-Methode anwenden.
Zeichnen Sie ein Rechteck um die beliebige Form. Nehmen Sie eine gleichmäßig verteilte PRNG-Quelle, z. Mersenne Twister, dann die Ausgabe durch Rechteck X, Y Längen mit Modulo-Funktion gebunden. Zähle die Nr. von zufälligen Punkten, die in Ihrer Form landen. Teilen Sie durch die Gesamtanzahl der generierten Punkte. Multiplizieren Sie diesen Quotienten mit der Fläche des Rechtecks. Mit jeder Iteration konvergieren Sie zum wahren Bereich. Der Algorithmus ist lächerlich parrallelisierbar und kann verwendet werden, um beliebig dimensionale Formvolumina zu berechnen, solange Sie feststellen können, ob eine R ^ N-Koordinate innerhalb der R ^ N-Grenze der Form liegt..
quelle
Ein anderer Ansatz: Nicht.
Stattdessen:
Im Grunde genommen ein Dreieck abschneiden. Die Fläche eines Dreiecks ist einfach und auf diese Weise haben wir die Segmentanzahl des Rests um eins verringert. Wiederholen, bis noch ein Dreieck übrig ist.
quelle