正如Martijn所说,我计算并设置了身体的质量数据。为此,我在假设密度均匀的情况下计算质心。我正在使用 LIBGDX,所以我需要一种在 java 中执行此操作的方法。我使用 Box2D 的源代码编写了例程。随意使用它来做任何你喜欢的事情。
EdgeShapes 没有质量,因此没有物理行为。要引起这种行为,需要手动计算。
public static MassData calculateMassData(List<Vector2> vertices,
float density) {
float k_inv3 = 1.0f / 3.0f;
float area = 0.0f;
float I = 0.0f;
Vector2 center = new Vector2();
Vector2 s = new Vector2();
for (int i = 0, size = vertices.size(); i < size; i++) {
s.add(vertices.get(i));
}
s.div(vertices.size());
for (int i = 0, size = vertices.size(); i < size; ++i) {
// Triangle vertices.
Vector2 e1 = new Vector2(vertices.get(i));
e1.sub(s);
Vector2 e2 = new Vector2(i + 1 < size ? vertices.get(i + 1)
: vertices.get(0));
e2.sub(s);
float D = e1.crs(e2);
float triangleArea = 0.5f * D;
area += triangleArea;
// Area weighted centroid
center.add(e1.cpy().add(e2).mul(k_inv3).mul(triangleArea));
float ex1 = e1.x, ey1 = e1.y;
float ex2 = e2.x, ey2 = e2.y;
float intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;
float inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;
I += (0.25f * k_inv3 * D) * (intx2 + inty2);
}
MassData data = new MassData();
// Total mass
data.mass = density * area;
center.mul(1.0f / area);
data.center.set(center.cpy().add(s));
// Inertia tensor relative to the local origin (point s).
data.I = density * I;
// Shift to center of mass then to original body origin.
data.I += data.mass
* (data.center.dot(data.center) - center.dot(center));
data.I = (data.I);
return data;
}
边缘形状的2个限制:
- 边缘形状不会与其他边缘形状发生冲突
- 边缘形状不是正常的多边形。对于仅使用边缘形状构建的任何多边形,都没有真正的外部/内部定义。
由于#2,其他物体可以在使用边缘形状构建的多边形内结束。
由于#1,我采用了不同的方法并使用一系列窄矩形构建了我的多边形。这运作良好,但不幸的是不能解决#2。
我不想将 PolygonShape 用于固定装置,因为我尝试建模的多边形很复杂。它可以有数百个顶点。
我尝试过对我的多边形进行三角剖分并从每个三角形中创建固定装置。不幸的是,生成的三角形面积对于 Box2D 来说通常太小,并且会导致 box2d 出现异常。
我对这里的其他解决方案持开放态度。