Ich habe ein 2D konvexes Polygon im 3D-Raum und eine Funktion zur Messung der Fläche des Polygons.
public double Fläche() {
if (vertices.size() >= 3) {
double Fläche = 0;
Vector3 Ursprung = vertices.get(0);
Vector3 vorher = vertices.get(1).clone();
vorher.sub(Ursprung);
for (int i = 2; i < vertices.size(); i++) {
Vector3 aktuell = vertices.get(i).clone();
aktuell.sub(Ursprung);
Vector3 kreuz = vorher.cross(aktuell);
Fläche += kreuz.magnitude();
vorher = aktuell;
}
Fläche /= 2;
return Fläche;
} else {
return 0;
}
}
Um zu testen, ob diese Methode bei allen Ausrichtungen des Polygons funktioniert, habe ich mein Programm so gemacht, dass es bei jeder Iteration das Polygon ein wenig dreht und die Fläche berechnet. Wie folgt...
Face f = poly.getFaces().get(0);
for (int i = 0; i < f.size(); i++) {
Vector3 v = f.getVertex(i);
v.rotate(0.1f, 0.2f, 0.3f);
}
if (blah % 1000 == 0)
System.out.println(blah + ":\t" + f.area());
Meine Methode scheint korrekt zu sein, wenn ich mit einem 20x20 Quadrat teste. Allerdings scheint die rotate-Methode (eine Methode in der Vector3-Klasse) etwas Fehler in die Position jedes Vertex im Polygon einzuführen, was die Flächenberechnung beeinflusst. Hier ist die Vector3.rotate() Methode
public void rotate(double xWinkel, double yWinkel, double zWinkel) {
double altY = y;
double altZ = z;
y = altY * Math.cos(xWinkel) - altZ * Math.sin(xWinkel);
z = altY * Math.sin(xWinkel) + altZ * Math.cos(xWinkel);
altZ = z;
double altX = x;
z = altZ * Math.cos(yWinkel) - altX * Math.sin(yWinkel);
x = altZ * Math.sin(yWinkel) + altX * Math.cos(yWinkel);
altX = x;
altY = y;
x = altX * Math.cos(zWinkel) - altY * Math.sin(zWinkel);
y = altX * Math.sin(zWinkel) + altY * Math.cos(zWinkel);
}
Hier ist die Ausgabe für mein Programm im Format "Iteration: Fläche":
0: 400.0
1000: 399.9999999999981
2000: 399.99999999999744
3000: 399.9999999999959
4000: 399.9999999999924
5000: 399.9999999999912
6000: 399.99999999999187
7000: 399.9999999999892
8000: 399.9999999999868
9000: 399.99999999998664
10000: 399.99999999998386
11000: 399.99999999998283
12000: 399.99999999998215
13000: 399.9999999999805
14000: 399.99999999998016
15000: 399.99999999997897
16000: 399.9999999999782
17000: 399.99999999997715
18000: 399.99999999997726
19000: 399.9999999999769
20000: 399.99999999997584
Weil dies letztendlich für eine Physik-Engine gedacht ist, möchte ich wissen, wie ich den kumulativen Fehler minimieren kann, da die Vector3.rotate() Methode sehr regelmäßig verwendet wird.
Danke!
Ein paar seltsame Anmerkungen:
-
Der Fehler ist proportional zur gedrehten Menge. d.h. größere Rotation pro Iteration -> größerer Fehler pro Iteration.
-
Es gibt mehr Fehler, wenn Double-Werte an die rotate-Funktion übergeben werden als wenn Float-Werte übergeben werden.