3D空間に2D凸多角形と多角形の面積を測定する関数があります。
public double area() {
if (vertices.size() >= 3) {
double area = 0;
Vector3 origin = vertices.get(0);
Vector3 prev = vertices.get(1).clone();
prev.sub(origin);
for (int i = 2; i < vertices.size(); i++) {
Vector3 current = vertices.get(i).clone();
current.sub(origin);
Vector3 cross = prev.cross(current);
area += cross.magnitude();
prev = current;
}
area /= 2;
return area;
} else {
return 0;
}
}
この方法がポリゴンのすべての方向で機能することをテストするために、プログラムで反復ごとに少し回転させて、面積を計算しました。そのようです...
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());
20x20の正方形でテストする場合、私の方法は正しいようです。ただし、rotateメソッド(Vector3クラスのメソッド)は、ポリゴン内の各頂点の位置にエラーを導入し、面積の計算に影響を与えるようです。これがVector3.rotate()メソッドです
public void rotate(double xAngle, double yAngle, double zAngle) {
double oldY = y;
double oldZ = z;
y = oldY * Math.cos(xAngle) - oldZ * Math.sin(xAngle);
z = oldY * Math.sin(xAngle) + oldZ * Math.cos(xAngle);
oldZ = z;
double oldX = x;
z = oldZ * Math.cos(yAngle) - oldX * Math.sin(yAngle);
x = oldZ * Math.sin(yAngle) + oldX * Math.cos(yAngle);
oldX = x;
oldY = y;
x = oldX * Math.cos(zAngle) - oldY * Math.sin(zAngle);
y = oldX * Math.sin(zAngle) + oldY * Math.cos(zAngle);
}
これが私のプログラムの「反復:領域」の形式での出力です。
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
これは最終的には物理エンジンを対象としているため、Vector3.rotate()メソッドが非常に定期的に使用されるため、累積エラーを最小限に抑える方法を知りたいと思います。
ありがとう!
いくつかの奇妙なメモ:
誤差は回転量に比例します。すなわち。反復ごとの回転数が大きい->反復ごとのエラーが大きい。
回転関数にdoubleを渡す場合は、floatを渡す場合よりもエラーが多くなります。