From 4b1c6a4f4bc6755bfc7f00be0c9cf427b737cadd Mon Sep 17 00:00:00 2001 From: JoePfeiffer Date: Tue, 21 Nov 2023 16:01:41 -0700 Subject: [PATCH] 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. --- .../rocketcomponent/SymmetricComponent.java | 76 ++----------------- 1 file changed, 6 insertions(+), 70 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/SymmetricComponent.java b/core/src/net/sf/openrocket/rocketcomponent/SymmetricComponent.java index 01349def2..7c9a22c75 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/SymmetricComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/SymmetricComponent.java @@ -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.