eliminate SymmetricComponent::integrateInertiaSurface()
Previously, the code calculated the volume of a component, and if that volume was too small calculated its moments of inertia based on the surface instead of the volume. The decision wasn't based on the thickness of the shell (which might have made sense to me), it was the actual volume. The result is any really small component had its moments of inertia calculated using this surface method, no matter how "solid" the object was. The cause of #2403 was that this method was used to calculate the moments of inertia in the .ork that failed, but the actual CG was used in the parallel axis theorem. This put the CG in a different place than a "surface CG" would have, so the longitudinal moment of inertia ended up less than 0 triggering the crash. Now, if a component is so small that's volume is 0 it is assumed its contribution to moment of inertia must also be negligible, so the moments of inertia are set to 0 in this case.
This commit is contained in:
parent
9fec2af7a8
commit
4b1c6a4f4b
@ -314,10 +314,7 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
|
||||
@Override
|
||||
public double getLongitudinalUnitInertia() {
|
||||
if (Double.isNaN(longitudinalInertia)) {
|
||||
if (getComponentVolume() > 0.0000001) // == 0.1cm^3
|
||||
integrateInertiaVolume();
|
||||
else
|
||||
integrateInertiaSurface();
|
||||
integrateInertiaVolume();
|
||||
}
|
||||
return longitudinalInertia;
|
||||
}
|
||||
@ -326,10 +323,7 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
|
||||
@Override
|
||||
public double getRotationalUnitInertia() {
|
||||
if (Double.isNaN(rotationalInertia)) {
|
||||
if (getComponentVolume() > 0.0000001) // == 0.1cm^3
|
||||
integrateInertiaVolume();
|
||||
else
|
||||
integrateInertiaSurface();
|
||||
integrateInertiaVolume();
|
||||
}
|
||||
return rotationalInertia;
|
||||
}
|
||||
@ -497,9 +491,11 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
|
||||
r1 = r2;
|
||||
x += l;
|
||||
}
|
||||
|
||||
|
||||
// a part so small it has no volume can't contribute to moment of inertia
|
||||
if (MathUtil.equals(vol, 0)) {
|
||||
integrateInertiaSurface();
|
||||
rotationalInertia = 0;
|
||||
longitudinalInertia = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -509,66 +505,6 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
|
||||
// Shift longitudinal inertia to CG
|
||||
longitudinalInertia = longitudinalInertia - pow2(getSymmetricComponentCG().x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Integrate the longitudinal and rotational inertia based on component surface area.
|
||||
* This method may be used only if the total volume is zero.
|
||||
*/
|
||||
private void integrateInertiaSurface() {
|
||||
double x, r1, r2;
|
||||
|
||||
longitudinalInertia = 0;
|
||||
rotationalInertia = 0;
|
||||
|
||||
if (getLength() <= 0) return;
|
||||
|
||||
final double l = getLength() / DIVISIONS;
|
||||
|
||||
r1 = getRadius(0);
|
||||
x = 0;
|
||||
|
||||
double surface = 0;
|
||||
|
||||
for (int n = 1; n <= DIVISIONS; n++) {
|
||||
/*
|
||||
* r1 and r2 are the two radii, outer is their average
|
||||
* x is the position of r1
|
||||
* hyp is the length of the hypotenuse from r1 to r2
|
||||
* height if the y-axis height of the component if not filled
|
||||
*/
|
||||
r2 = getRadius(x + l);
|
||||
final double hyp = MathUtil.hypot(r2 - r1, l);
|
||||
final double outer = (r1 + r2) / 2;
|
||||
|
||||
final double dS = hyp * (r1 + r2) * Math.PI;
|
||||
|
||||
rotationalInertia += dS * pow2(outer);
|
||||
longitudinalInertia += dS * ((6 * pow2(outer) + pow2(l)) / 12 + pow2(x + l / 2));
|
||||
|
||||
surface += dS;
|
||||
|
||||
// Update for next iteration
|
||||
r1 = r2;
|
||||
x += l;
|
||||
}
|
||||
|
||||
if (MathUtil.equals(surface, 0)) {
|
||||
longitudinalInertia = 0;
|
||||
rotationalInertia = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
longitudinalInertia /= surface;
|
||||
rotationalInertia /= surface;
|
||||
|
||||
// Shift longitudinal inertia to CG
|
||||
longitudinalInertia = longitudinalInertia - pow2(getSymmetricComponentCG().x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Invalidates the cached volume and CG information.
|
||||
|
Loading…
x
Reference in New Issue
Block a user