Merge commit '42b2e5ca519766e37ce6941ba4faecc9691cc403' into upstream
[debian/openrocket] / core / src / net / sf / openrocket / rocketcomponent / SymmetricComponent.java
index 5dc1835463e9ed3bf2ad72207c0835607e2b167c..7b455fa8593f306e9c88d019bbda1d9b4bd61c07 100644 (file)
@@ -6,6 +6,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
+import net.sf.openrocket.preset.ComponentPreset;
 import net.sf.openrocket.util.Coordinate;
 import net.sf.openrocket.util.MathUtil;
 
@@ -146,10 +147,14 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
        
 
        @Override
-       protected void loadFromPreset(RocketComponent preset) {
-               SymmetricComponent c = (SymmetricComponent) preset;
-               this.setThickness(c.getThickness());
-               this.setFilled(c.isFilled());
+       protected void loadFromPreset(ComponentPreset preset) {
+               if ( preset.has(ComponentPreset.THICKNESS) ) {
+                       this.thickness = preset.get(ComponentPreset.THICKNESS);
+                       this.filled = false;
+               }
+               if ( preset.has(ComponentPreset.FILLED)) {
+                       this.filled = true;
+               }
                
                super.loadFromPreset(preset);
        }
@@ -293,9 +298,8 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
 
                // Integrate for volume, CG, wetted area and planform area
                
-               final double l = length / DIVISIONS;
-               final double pil = Math.PI * l; // PI * l
-               final double pil3 = Math.PI * l / 3; // PI * l/3
+               final double step = length / DIVISIONS;
+               final double pi3 = Math.PI / 3.0;
                r1 = getRadius(0);
                x = 0;
                wetArea = 0;
@@ -312,25 +316,44 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
                         * hyp is the length of the hypotenuse from r1 to r2
                         * height if the y-axis height of the component if not filled
                         */
+                       /*
+                        * l is the step size for the current loop.  Could also be called delta-x.
+                        * 
+                        * to account for accumulated errors in the x position during the loop
+                        * during the last iteration (n== DIVISIONS) we recompute l to be
+                        * whatever is left.
+                        */
+                       double l = (n==DIVISIONS) ? length -x : step;
 
-                       r2 = getRadius(x + l);
+                       // Further to prevent round off error from the previous statement,
+                       // we clamp r2 to length at the last iteration.
+                       r2 = getRadius((n==DIVISIONS) ? length : x + l);
+                       
                        final double hyp = MathUtil.hypot(r2 - r1, l);
                        
-
                        // Volume differential elements
                        final double dV;
                        final double dFullV;
                        
-                       dFullV = pil3 * (r1 * r1 + r1 * r2 + r2 * r2);
-                       if (filled || r1 < thickness || r2 < thickness) {
-                               // Filled piece
+                       dFullV = pi3 * l * (r1 * r1 + r1 * r2 + r2 * r2);
+                       
+                       if ( filled ) {
                                dV = dFullV;
                        } else {
-                               // Hollow piece
-                               final double height = thickness * hyp / l;
-                               dV = MathUtil.max(pil * height * (r1 + r2 - height), 0);
+                               // hollow
+                               // Thickness is normal to the surface of the component
+                               // here we use simple trig to project the Thickness
+                               // on to the y dimension (radius).
+                               double height = thickness * hyp / l;
+                               if (r1 < height || r2 < height) {
+                                       // Filled portion of piece
+                                       dV = dFullV;
+                               } else {
+                                       // Hollow portion of piece
+                                       dV = MathUtil.max(Math.PI* l * height * (r1 + r2 - height), 0);
+                               }
                        }
-                       
+
                        // Add to the volume-related components
                        volume += dV;
                        fullVolume += dFullV;
@@ -343,7 +366,7 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
                        final double p = l * (r1 + r2);
                        planArea += p;
                        planCenter += (x + l / 2) * p;
-                       
+
                        // Update for next iteration
                        r1 = r2;
                        x += l;
@@ -358,10 +381,10 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
                        volume = 0;
                        cg = new Coordinate(length / 2, 0, 0, 0);
                } else {
-                       // getComponentMass is safe now
-                       // Use super.getComponentMass() to ensure only the transition shape mass
-                       // is used, not the shoulders
-                       cg = new Coordinate(cgx / volume, 0, 0, super.getComponentMass());
+                       // the mass of this shape is the material density * volume.
+                       // it cannot come from super.getComponentMass() since that 
+                       // includes the shoulders
+                       cg = new Coordinate(cgx / volume, 0, 0, getMaterial().getDensity() * volume );
                }
        }
        
@@ -444,7 +467,7 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
                final double l = length / DIVISIONS;
                
                r1 = getRadius(0);
-               System.out.println(r1);
+               //System.out.println(r1);
                x = 0;
                
                longitudinalInertia = 0;