diff --git a/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java b/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java index 4667476c8..c4ac8c874 100644 --- a/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java +++ b/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java @@ -2,7 +2,6 @@ package net.sf.openrocket.aerodynamics; import static net.sf.openrocket.util.MathUtil.pow2; -import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; @@ -23,6 +22,7 @@ import net.sf.openrocket.rocketcomponent.InstanceMap; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.SymmetricComponent; +import net.sf.openrocket.util.ArrayList; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.PolyInterpolator; @@ -96,7 +96,6 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator { // Calculate non-axial force data AerodynamicForces total = calculateNonAxialForces(configuration, conditions, map, warnings); - // Calculate friction data total.setFrictionCD(calculateFrictionDrag(configuration, conditions, map, warnings)); total.setPressureCD(calculatePressureDrag(configuration, conditions, map, warnings)); @@ -174,7 +173,6 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator { if (calcMap == null) buildCalcMap(configuration); - if( ! isContinuous( configuration.getRocket() ) ){ warnings.add( Warning.DIAMETER_DISCONTINUITY); } diff --git a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java index a5607615e..0e80fbf9b 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java +++ b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java @@ -55,24 +55,6 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC separations.reset(fcid); } - /** - * {@inheritDoc} - * not strictly accurate, but this should provide an acceptable estimate for total vehicle size - */ - @Override - public Collection getComponentBounds() { - Collection bounds = new ArrayList(8); - Coordinate[] instanceLocations = this.getInstanceLocations(); - double x_min = instanceLocations[0].x; - double x_max = x_min + this.length; - double r_max = 0; - - addBound(bounds, x_min, r_max); - addBound(bounds, x_max, r_max); - - return bounds; - } - /** * Check whether the given type can be added to this component. A Stage allows * only BodyComponents to be added. diff --git a/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java b/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java index be4d06a9a..b2a9f134b 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java +++ b/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java @@ -10,6 +10,7 @@ import net.sf.openrocket.motor.MotorConfiguration; import net.sf.openrocket.motor.MotorConfigurationSet; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; @@ -296,52 +297,7 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial private static double getFilledVolume(double r, double l) { return Math.PI * r * r * l; } - - - /** - * Adds bounding coordinates to the given set. The body tube will fit within the - * convex hull of the points. - * - * Currently the points are simply a rectangular box around the body tube. - */ - @Override - public Collection getComponentBounds() { - Collection bounds = new ArrayList(8); - double x_min_shape = 0; - double x_max_shape = this.length; - double r_max_shape = getOuterRadius(); - Coordinate[] locs = this.getLocations(); - // not strictly accurate, but this should provide an acceptable estimate for total vehicle size - double x_min_inst = Double.MAX_VALUE; - double x_max_inst = Double.MIN_VALUE; - double r_max_inst = 0.0; - - // refactor: get component inherent bounds - for (Coordinate cur : locs) { - double x_cur = cur.x; - double r_cur = MathUtil.hypot(cur.y, cur.z); - if (x_min_inst > x_cur) { - x_min_inst = x_cur; - } - if (x_max_inst < x_cur) { - x_max_inst = x_cur; - } - if (r_cur > r_max_inst) { - r_max_inst = r_cur; - } - } - - // combine the position bounds with the inherent shape bounds - double x_min = x_min_shape + x_min_inst; - double x_max = x_max_shape + x_max_inst; - double r_max = r_max_shape + r_max_inst; - - addBoundingBox(bounds, x_min, x_max, r_max); - return bounds; - } - - /** * Check whether the given type can be added to this component. BodyTubes allow any * InternalComponents or ExternalComponents, excluding BodyComponents, to be added. diff --git a/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java b/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java index 24468aeb3..3aec4aea7 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java +++ b/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java @@ -9,6 +9,7 @@ import org.slf4j.LoggerFactory; import net.sf.openrocket.rocketcomponent.position.AxialMethod; import net.sf.openrocket.rocketcomponent.position.AxialPositionable; +import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.Coordinate; @@ -46,14 +47,6 @@ public abstract class ComponentAssembly extends RocketComponent implements Axia public double getAxialOffset() { return getAxialOffset( this.axialMethod ); } - - /** - * Null method (ComponentAssembly has no bounds of itself). - */ - @Override - public Collection getComponentBounds() { - return Collections.emptyList(); - } /** * Null method (ComponentAssembly has no mass of itself). @@ -107,6 +100,17 @@ public abstract class ComponentAssembly extends RocketComponent implements Axia } return outerRadius; } + + /** + * We'll find the bounding box of a component by iterating an + * InstanceMap, not by performing a treewalk of the component. + * So, anything subclassed from a ComponentAssembly will just + * return an empty bounding box + */ + @Override + public BoundingBox getBoundingBox() { + return new BoundingBox(); + } /** * Components have no aerodynamic effect, so return false. diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index 52ba40843..e63bf15d5 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -709,53 +709,16 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab BoundingBox singleFinBounds= new BoundingBox().update(getFinPoints()); final double finLength = singleFinBounds.max.x; final double finHeight = singleFinBounds.max.y; - + + /* BoundingBox compBox = new BoundingBox().update(getComponentLocations()); BoundingBox finSetBox = new BoundingBox( compBox.min.sub( 0, finHeight, finHeight ), compBox.max.add( finLength, finHeight, finHeight )); return finSetBox; - } - - /** - * Adds bounding coordinates to the given set. The body tube will fit within the - * convex hull of the points. - * - * Currently the points are simply a rectangular box around the body tube. - */ - @Override - public Collection getComponentBounds() { - Collection bounds = new ArrayList(8); - - // should simply return this component's bounds in this component's body frame. - - double x_min = Double.MAX_VALUE; - double x_max = Double.MIN_VALUE; - double r_max = 0.0; - - for (Coordinate point : getFinPoints()) { - double hypot = MathUtil.hypot(point.y, point.z); - double x_cur = point.x; - if (x_min > x_cur) { - x_min = x_cur; - } - if (x_max < x_cur) { - x_max = x_cur; - } - if (r_max < hypot) { - r_max = hypot; - } - } - - Coordinate location = this.getLocations()[0]; - x_max += location.x; - - if( parent instanceof SymmetricComponent){ - r_max += ((SymmetricComponent)parent).getRadius(0); - } - - addBoundingBox(bounds, x_min, x_max, r_max); - return bounds; + */ + + return new BoundingBox(0.0, finLength, finHeight); } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java b/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java index 4bb7fdc8d..f3b3e3e74 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java @@ -63,7 +63,7 @@ public class FlightConfiguration implements FlightConfigurableParameter motors = new HashMap(); private int boundsModID = -1; - private BoundingBox cachedBounds = new BoundingBox(); + private BoundingBox cachedBoundingBox = new BoundingBox(); private double cachedLength = -1; private int refLengthModID = -1; @@ -501,18 +501,6 @@ public class FlightConfiguration implements FlightConfigurableParameterCollection containing coordinates bounding the rocket. - * - * @deprecated Migrate to .getBoundingBox(), when practical. - */ - @Deprecated - public Collection getBounds() { - return getBoundingBox().toCollection(); - } - /** * Return the bounding box of the current configuration. * @@ -520,22 +508,34 @@ public class FlightConfiguration implements FlightConfigurableParameter> entry: imap.entrySet() ) { + final RocketComponent comp = entry.getKey(); + if (this.isComponentActive(comp)) { + + // iterate across all componenent instances + final ArrayList contextList = entry.getValue(); + + for(InstanceContext context: contextList ) { + BoundingBox instanceBox = new BoundingBox(context.transform.transform(comp.getBoundingBox().min), + context.transform.transform(comp.getBoundingBox().max)); + bounds.update(instanceBox); + } + } } boundsModID = rocket.getModID(); cachedLength = bounds.span().x; - cachedBounds.update( bounds ); + cachedBoundingBox.update( bounds ); } /** @@ -546,7 +546,7 @@ public class FlightConfiguration implements FlightConfigurableParametertrue diff --git a/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java b/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java index 0824a3aef..854b67477 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java +++ b/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java @@ -8,6 +8,7 @@ import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.ComponentPreset.Type; import net.sf.openrocket.rocketcomponent.position.*; import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; @@ -186,13 +187,10 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, C public double getComponentVolume() { return length * Math.PI * (MathUtil.pow2(radius) - MathUtil.pow2(radius - thickness)); } - + @Override - public Collection getComponentBounds() { - ArrayList set = new ArrayList(); - addBound(set, 0, radius); - addBound(set, length, radius); - return set; + public BoundingBox getBoundingBox() { + return new BoundingBox(0, length, radius); } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/MassObject.java b/core/src/net/sf/openrocket/rocketcomponent/MassObject.java index b018919d2..9af0c8ae3 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/MassObject.java +++ b/core/src/net/sf/openrocket/rocketcomponent/MassObject.java @@ -133,13 +133,4 @@ public abstract class MassObject extends InternalComponent { public final double getRotationalUnitInertia() { return pow2(radius) / 2; } - - @Override - public final Collection getComponentBounds() { - Collection c = new ArrayList(); - addBound(c, 0, radius); - addBound(c, length, radius); - return c; - } - } diff --git a/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java b/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java index daf79abda..0cfd8b071 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java +++ b/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java @@ -44,33 +44,6 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo return trans.get("BoosterSet.BoosterSet"); } - // not strictly accurate, but this should provide an acceptable estimate for total vehicle size - @Override - public Collection getComponentBounds() { - Collection bounds = new ArrayList(8); - double x_min = Double.MAX_VALUE; - double x_max = Double.MIN_VALUE; - double r_max = 0; - - Coordinate[] instanceLocations = this.getComponentLocations(); - - for (Coordinate currentInstanceLocation : instanceLocations) { - if (x_min > (currentInstanceLocation.x)) { - x_min = currentInstanceLocation.x; - } - if (x_max < (currentInstanceLocation.x + this.length)) { - x_max = currentInstanceLocation.x + this.length; - } - if (r_max < (this.getRadiusOffset())) { - r_max = this.getRadiusOffset(); - } - } - addBound(bounds, x_min, r_max); - addBound(bounds, x_max, r_max); - - return bounds; - } - /** * Check whether the given type can be added to this component. A Stage allows * only BodyComponents to be added. diff --git a/core/src/net/sf/openrocket/rocketcomponent/PodSet.java b/core/src/net/sf/openrocket/rocketcomponent/PodSet.java index e22fc51aa..2e3a72275 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/PodSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/PodSet.java @@ -45,33 +45,6 @@ public class PodSet extends ComponentAssembly implements RingInstanceable { } - // not strictly accurate, but this should provide an acceptable estimate for total vehicle size - @Override - public Collection getComponentBounds() { - Collection bounds = new ArrayList(8); - double x_min = Double.MAX_VALUE; - double x_max = Double.MIN_VALUE; - double r_max = 0; - - Coordinate[] instanceLocations = this.getComponentLocations(); - - for (Coordinate currentInstanceLocation : instanceLocations) { - if (x_min > (currentInstanceLocation.x)) { - x_min = currentInstanceLocation.x; - } - if (x_max < (currentInstanceLocation.x + this.length)) { - x_max = currentInstanceLocation.x + this.length; - } - if (r_max < (this.getRadiusOffset())) { - r_max = this.getRadiusOffset(); - } - } - addBound(bounds, x_min, r_max); - addBound(bounds, x_max, r_max); - - return bounds; - } - /** * Check whether the given type can be added to this component. A Stage allows * only BodyComponents to be added. diff --git a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java index df6ea275a..ab39d492b 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java @@ -11,6 +11,7 @@ import net.sf.openrocket.rocketcomponent.position.AnglePositionable; import net.sf.openrocket.rocketcomponent.position.AxialMethod; import net.sf.openrocket.rocketcomponent.position.AxialPositionable; import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; @@ -232,6 +233,13 @@ public class RailButton extends ExternalComponent implements AnglePositionable, public Type getPresetType() { return ComponentPreset.Type.RAIL_BUTTON; } + + @Override + public BoundingBox getBoundingBox() { + final double r = outerDiameter_m / 2.0; + return new BoundingBox(new Coordinate(-r, -r, 0), + new Coordinate(r, r, totalHeight_m)); + } @Override public void componentChanged(ComponentChangeEvent e) { @@ -287,21 +295,6 @@ public class RailButton extends ExternalComponent implements AnglePositionable, public String getPatternName(){ return (this.getInstanceCount() + "-Line"); } - - @Override - public Collection getComponentBounds() { - final double r = outerDiameter_m / 2.0; - ArrayList set = new ArrayList(); - set.add(new Coordinate(r, totalHeight_m, r)); - set.add(new Coordinate(r, totalHeight_m, -r)); - set.add(new Coordinate(r, 0, r)); - set.add(new Coordinate(r, 0, -r)); - set.add(new Coordinate(-r, 0, r)); - set.add(new Coordinate(-r, 0, -r)); - set.add(new Coordinate(-r, totalHeight_m, r)); - set.add(new Coordinate(-r, totalHeight_m, -r)); - return set; - } @Override public Coordinate getComponentCG() { diff --git a/core/src/net/sf/openrocket/rocketcomponent/RingComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RingComponent.java index 5dbf4d5ba..0365a76a3 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RingComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RingComponent.java @@ -162,14 +162,6 @@ public abstract class RingComponent extends StructuralComponent implements Coaxi fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); } - @Override - public Collection getComponentBounds() { - List bounds = new ArrayList(); - addBound(bounds, 0, getOuterRadius()); - addBound(bounds, length, getOuterRadius()); - return bounds; - } - @Override public Coordinate getComponentCG() { Coordinate cg = Coordinate.ZERO; @@ -195,7 +187,6 @@ public abstract class RingComponent extends StructuralComponent implements Coaxi getMaterial().getDensity()) * getInstanceCount(); } - @Override public double getLongitudinalUnitInertia() { return ringLongitudinalUnitInertia(getOuterRadius(), getInnerRadius(), getLength()); diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index fc20dc813..1d5794736 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -19,6 +19,7 @@ import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.rocketcomponent.position.AxialMethod; import net.sf.openrocket.rocketcomponent.position.RadiusMethod; import net.sf.openrocket.util.ArrayList; +import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.ChangeSource; import net.sf.openrocket.util.Color; @@ -222,14 +223,13 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab /** - * Return a collection of bounding coordinates. The coordinates must be such that - * the component is fully enclosed in their convex hull. + * Return bounding box of component. * * Note: this function gets the bounds only for this component. Subchildren must be called individually. * * @return a collection of coordinates that bound the component. */ - public abstract Collection getComponentBounds(); + public abstract BoundingBox getBoundingBox(); /** * Return true if the component may have an aerodynamic effect on the rocket. @@ -1902,7 +1902,9 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab /** - * Helper method to add two points on opposite corners of a box around the rocket centerline. This box will be (x_max - x_min) long, and 2*r wide/high. + * Helper method to add two points on opposite corners of a box + * around the component centerline. This box will be (x_max - + * x_min) long, and 2*r wide/high. */ protected static final void addBoundingBox(Collection bounds, double x_min, double x_max, double r) { bounds.add(new Coordinate(x_min, -r, -r)); diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketUtils.java b/core/src/net/sf/openrocket/rocketcomponent/RocketUtils.java index f875c2b76..6776e83c1 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketUtils.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketUtils.java @@ -1,3 +1,4 @@ +// this class is only used by the Android application package net.sf.openrocket.rocketcomponent; import java.util.Collection; @@ -7,20 +8,6 @@ import net.sf.openrocket.util.Coordinate; public abstract class RocketUtils { public static double getLength(Rocket rocket) { - double length = 0; - Collection bounds = rocket.getSelectedConfiguration().getBounds(); - if (!bounds.isEmpty()) { - double minX = Double.POSITIVE_INFINITY, maxX = Double.NEGATIVE_INFINITY; - for (Coordinate c : bounds) { - if (c.x < minX) - minX = c.x; - if (c.x > maxX) - maxX = c.x; - } - length = maxX - minX; - } - return length; + return rocket.getSelectedConfiguration().getLength(); } - - } diff --git a/core/src/net/sf/openrocket/rocketcomponent/Sleeve.java b/core/src/net/sf/openrocket/rocketcomponent/Sleeve.java index aafff5422..86a5d9191 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Sleeve.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Sleeve.java @@ -2,6 +2,7 @@ package net.sf.openrocket.rocketcomponent; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; @@ -82,9 +83,6 @@ public class Sleeve extends RingComponent { thickness = t; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); } - - - @Override public void setInnerRadiusAutomatic(boolean auto) { diff --git a/core/src/net/sf/openrocket/rocketcomponent/SymmetricComponent.java b/core/src/net/sf/openrocket/rocketcomponent/SymmetricComponent.java index a530bfe94..e4f0fe36f 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/SymmetricComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/SymmetricComponent.java @@ -8,6 +8,7 @@ import java.util.List; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.rocketcomponent.position.AxialMethod; +import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; @@ -133,24 +134,17 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); clearPreset(); } - - + /** - * Adds component bounds at a number of points between 0...length. + * Are there any components whose max diameter isn't at either the + * fore or aft end? I don't know of any. */ @Override - public Collection getComponentBounds() { - List list = new ArrayList(20); - for (int n = 0; n <= 5; n++) { - double x = n * length / 5; - double r = getRadius(x); - addBound(list, x, r); - } - return list; + public BoundingBox getBoundingBox() { + return new BoundingBox(0, getLength(), + Math.max(getForeRadius(), getAftRadius())); } - - @Override protected void loadFromPreset(ComponentPreset preset) { if ( preset.has(ComponentPreset.THICKNESS) ) { diff --git a/core/src/net/sf/openrocket/rocketcomponent/Transition.java b/core/src/net/sf/openrocket/rocketcomponent/Transition.java index d89f6de69..ada0e9fb1 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Transition.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Transition.java @@ -10,6 +10,7 @@ import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.ComponentPreset.Type; import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; @@ -433,16 +434,22 @@ public class Transition extends SymmetricComponent { return Math.max(getRadius(x) - thickness, 0); } - - + /** + * bounding box of transition + * + * It's tempting to ignore the shoulders (if any) on the grounds + * that they will be covered by the fore and aft body tubes, but + * including them won't cause any errors + * + * we will assume the maximum radius will occur at either the fore + * or aft end -- this is true for the transitions that are + * currently allowed, but could conceivably change in the future + */ @Override - public Collection getComponentBounds() { - Collection bounds = super.getComponentBounds(); - if (foreShoulderLength > 0.001) - addBound(bounds, -foreShoulderLength, foreShoulderRadius); - if (aftShoulderLength > 0.001) - addBound(bounds, getLength() + aftShoulderLength, aftShoulderRadius); - return bounds; + public BoundingBox getBoundingBox() { + return new BoundingBox(-getForeShoulderLength(), + getLength() + getAftShoulderLength(), + Math.max(getForeRadius(), getAftRadius())); } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/TubeFinSet.java b/core/src/net/sf/openrocket/rocketcomponent/TubeFinSet.java index aa9ad73ab..4f6b23aa0 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/TubeFinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/TubeFinSet.java @@ -10,6 +10,7 @@ import net.sf.openrocket.preset.ComponentPreset.Type; import net.sf.openrocket.rocketcomponent.position.AxialMethod; import net.sf.openrocket.rocketcomponent.position.AxialPositionable; import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.Transformation; @@ -304,16 +305,10 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable { // TODO Auto-generated method stub return false; } - + @Override - public Collection getComponentBounds() { - List bounds = new ArrayList(); - double r = getBodyRadius(); - - addBound(bounds, 0, 2 * (r + outerRadius)); - addBound(bounds, length, 2 * (r + outerRadius)); - - return bounds; + public BoundingBox getBoundingBox() { + return new BoundingBox(0, length, outerRadius); } /** diff --git a/core/src/net/sf/openrocket/simulation/SimulationStatus.java b/core/src/net/sf/openrocket/simulation/SimulationStatus.java index 9ea75832d..1420b4166 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationStatus.java +++ b/core/src/net/sf/openrocket/simulation/SimulationStatus.java @@ -127,11 +127,7 @@ public class SimulationStatus implements Monitorable { } } if (!Double.isNaN(lugPosition)) { - double maxX = 0; - for (Coordinate c : this.configuration.getBounds()) { - if (c.x > maxX) - maxX = c.x; - } + double maxX = this.configuration.getBoundingBox().max.x; if (maxX >= lugPosition) { length = Math.max(0, length - (maxX - lugPosition)); } diff --git a/core/src/net/sf/openrocket/util/BoundingBox.java b/core/src/net/sf/openrocket/util/BoundingBox.java index 6d5f46eb8..2b456cac6 100644 --- a/core/src/net/sf/openrocket/util/BoundingBox.java +++ b/core/src/net/sf/openrocket/util/BoundingBox.java @@ -17,6 +17,11 @@ public class BoundingBox { this.min = _min.clone(); this.max = _max.clone(); } + + public BoundingBox(double xmin, double xmax, double rad) { + min = new Coordinate(xmin, -rad, -rad); + max = new Coordinate(xmax, rad, rad); + } public void clear() { min = Coordinate.MAX.setWeight( 0.0); @@ -113,8 +118,14 @@ public class BoundingBox { update_z_max(other.max.z); return this; } - - public Coordinate span() { return max.sub( min ); } + + public Coordinate span() { + Coordinate tmp = max.sub( min ); + return new Coordinate(Math.max(tmp.x, 0.0), + Math.max(tmp.y, 0.0), + Math.max(tmp.z, 0.0), + Math.max(tmp.weight, 0.0)); + } public Coordinate[] toArray() { return new Coordinate[] { this.min, this.max }; diff --git a/openrocket.log b/openrocket.log deleted file mode 100644 index d5c1f8088..000000000 --- a/openrocket.log +++ /dev/null @@ -1 +0,0 @@ -Error: Unable to access jarfile OpenRocket.jar diff --git a/swing/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java b/swing/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java index 8b01b734e..6d74f4a37 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java @@ -49,6 +49,7 @@ import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Preferences; +import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; @@ -468,64 +469,21 @@ public class RocketFigure3d extends JPanel implements GLEventListener { redrawExtras = true; } - @SuppressWarnings("unused") - private static class Bounds { - double xMin, xMax, xSize; - double yMin, yMax, ySize; - double zMin, zMax, zSize; - double rMax; - } - - private Bounds cachedBounds = null; - - /** - * Calculates the bounds for the current configuration - * - * @return - */ - private Bounds calculateBounds() { - if (cachedBounds != null) { - return cachedBounds; - } else { - final Bounds b = new Bounds(); - final FlightConfiguration configuration = rkt.getSelectedConfiguration(); - final Collection bounds = configuration.getBounds(); - for (Coordinate c : bounds) { - b.xMax = Math.max(b.xMax, c.x); - b.xMin = Math.min(b.xMin, c.x); - - b.yMax = Math.max(b.yMax, c.y); - b.yMin = Math.min(b.yMin, c.y); - - b.zMax = Math.max(b.zMax, c.z); - b.zMin = Math.min(b.zMin, c.z); - - double r = MathUtil.hypot(c.y, c.z); - b.rMax = Math.max(b.rMax, r); - } - b.xSize = b.xMax - b.xMin; - b.ySize = b.yMax - b.yMin; - b.zSize = b.zMax - b.zMin; - cachedBounds = b; - return b; - } - } - private void setupView(final GL2 gl, final GLU glu) { gl.glLoadIdentity(); gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_POSITION, lightPosition, 0); - // Get the bounds - final Bounds b = calculateBounds(); + // Get the bounding box + final BoundingBox b = rkt.getSelectedConfiguration().getBoundingBox(); // Calculate the distance needed to fit the bounds in both the X and Y // direction // Add 10% for space around it. - final double dX = (b.xSize * 1.2 / 2.0) + final double dX = (b.max.x * 1.2 / 2.0) / Math.tan(Math.toRadians(fovX / 2.0)); - final double dY = (b.rMax * 2.0 * 1.2 / 2.0) + final double dY = (b.max.y * 2.0 * 1.2 / 2.0) / Math.tan(Math.toRadians(fovY / 2.0)); // Move back the greater of the 2 distances @@ -535,7 +493,8 @@ public class RocketFigure3d extends JPanel implements GLEventListener { gl.glRotated(roll * (180.0 / Math.PI), 1, 0, 0); // Center the rocket in the view. - gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0); + // gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0); + gl.glTranslated((b.min.x - b.max.x) / 2.0, 0, 0); //Change to LEFT Handed coordinates gl.glScaled(1, 1, -1); @@ -554,7 +513,6 @@ public class RocketFigure3d extends JPanel implements GLEventListener { */ public void updateFigure() { log.debug("3D Figure Updated"); - cachedBounds = null; if (canvas != null) { ((GLAutoDrawable) canvas).invoke(true, new GLRunnable() { @Override diff --git a/swing/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java index d4f6f54ea..42f657060 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java @@ -2,7 +2,6 @@ package net.sf.openrocket.gui.figure3d; import java.awt.Point; import java.nio.ByteBuffer; -import java.util.ArrayList; import java.util.Collection; import java.util.Map; import java.util.Set; @@ -28,6 +27,7 @@ import net.sf.openrocket.rocketcomponent.InstanceContext; import net.sf.openrocket.rocketcomponent.InstanceMap; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.util.ArrayList; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Transformation; diff --git a/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java index a0f44b54d..cd8229381 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java @@ -25,6 +25,7 @@ import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.Transition; import net.sf.openrocket.rocketcomponent.Transition.Shape; import net.sf.openrocket.rocketcomponent.TubeFinSet; +import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Transformation; @@ -121,12 +122,57 @@ public class ComponentRenderer { } else if ( c instanceof ParallelStage ) { } else if ( c instanceof PodSet ) { } else { - renderOther(gl, c); + renderBoundingBox(gl, c); } } + /** + * If I don't have a method to render an object, I'll render its bounding box + */ + private void renderBoundingBox(GL2 gl, RocketComponent c) { + BoundingBox box = c.getBoundingBox(); + + // rectangle at forward end + gl.glBegin(GL.GL_LINES); + gl.glVertex3d(box.min.x, box.min.y, box.min.z); + gl.glVertex3d(box.min.x, box.max.y, box.min.z); + gl.glVertex3d(box.min.x, box.max.y, box.max.z); + gl.glVertex3d(box.min.x, box.max.x, box.min.z); + gl.glEnd(); + + // rectangle at aft end + gl.glBegin(GL.GL_LINES); + gl.glVertex3d(box.max.x, box.min.y, box.min.z); + gl.glVertex3d(box.max.x, box.max.y, box.min.z); + gl.glVertex3d(box.max.x, box.max.y, box.max.z); + gl.glVertex3d(box.max.x, box.max.x, box.min.z); + gl.glEnd(); + + // connect forward and aft rectangles + gl.glBegin(GL.GL_LINES); + gl.glVertex3d(box.min.x, box.min.y, box.min.z); + gl.glVertex3d(box.max.x, box.min.y, box.min.z); + gl.glEnd(); + + gl.glBegin(GL.GL_LINES); + gl.glVertex3d(box.min.x, box.max.y, box.min.z); + gl.glVertex3d(box.max.x, box.max.y, box.min.z); + gl.glEnd(); + + gl.glBegin(GL.GL_LINES); + gl.glVertex3d(box.min.x, box.min.y, box.max.z); + gl.glVertex3d(box.max.x, box.min.y, box.max.z); + gl.glEnd(); + + gl.glBegin(GL.GL_LINES); + gl.glVertex3d(box.min.x, box.max.y, box.max.z); + gl.glVertex3d(box.max.x, box.max.y, box.max.z); + gl.glEnd(); + } + + /* private void renderOther(GL2 gl, RocketComponent c) { gl.glBegin(GL.GL_LINES); for (Coordinate cc : c.getComponentBounds()) { @@ -137,7 +183,7 @@ public class ComponentRenderer { } gl.glEnd(); } - + */ private void renderTransition(GL2 gl, Transition t, Surface which) { if (which == Surface.OUTSIDE || which == Surface.INSIDE) { diff --git a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java index 7e92db8b4..d6212c616 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java @@ -52,6 +52,7 @@ import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Preferences; +import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.Color; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; @@ -92,7 +93,6 @@ public class PhotoPanel extends JPanel implements GLEventListener { @Override public boolean run(final GLAutoDrawable drawable) { PhotoPanel.this.configuration = doc.getSelectedConfiguration(); - cachedBounds = null; rr = new RealisticRenderer(doc); rr.init(drawable); @@ -246,11 +246,11 @@ public class PhotoPanel extends JPanel implements GLEventListener { draw(drawable, 0); if (p.isMotionBlurred()) { - Bounds b = calculateBounds(); + BoundingBox b = configuration.getBoundingBox(); float m = .6f; int c = 10; - float d = (float) b.xSize / 25.0f; + float d = (float) (b.max.x - b.min.x) / 25.0f; gl.glAccum(GL2.GL_LOAD, m); @@ -391,11 +391,11 @@ public class PhotoPanel extends JPanel implements GLEventListener { gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_SPECULAR, new float[] { color[0], color[1], color[2], 1 }, 0); - Bounds b = calculateBounds(); + BoundingBox b = configuration.getBoundingBox(); gl.glLightf(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_QUADRATIC_ATTENUATION, 20f); gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_POSITION, - new float[] { (float) (b.xMax + .1f), 0, 0, 1 }, 0); + new float[] { (float) (b.max.x + .1f), 0, 0, 1 }, 0); gl.glEnable(GLLightingFunc.GL_LIGHT2); } else { gl.glDisable(GLLightingFunc.GL_LIGHT2); @@ -478,56 +478,14 @@ public class PhotoPanel extends JPanel implements GLEventListener { ratio = (double) w / (double) h; } - @SuppressWarnings("unused") - private static class Bounds { - double xMin, xMax, xSize; - double yMin, yMax, ySize; - double zMin, zMax, zSize; - double rMax; - } - - private Bounds cachedBounds = null; - - /** - * Calculates the bounds for the current configuration - * - * @return - */ - private Bounds calculateBounds() { - if (cachedBounds != null) { - return cachedBounds; - } else { - final Bounds b = new Bounds(); - final Collection bounds = configuration.getBounds(); - for (Coordinate c : bounds) { - b.xMax = Math.max(b.xMax, c.x); - b.xMin = Math.min(b.xMin, c.x); - - b.yMax = Math.max(b.yMax, c.y); - b.yMin = Math.min(b.yMin, c.y); - - b.zMax = Math.max(b.zMax, c.z); - b.zMin = Math.min(b.zMin, c.z); - - double r = MathUtil.hypot(c.y, c.z); - b.rMax = Math.max(b.rMax, r); - } - b.xSize = b.xMax - b.xMin; - b.ySize = b.yMax - b.yMin; - b.zSize = b.zMax - b.zMin; - cachedBounds = b; - return b; - } - } - private void setupModel(final GL2 gl) { - // Get the bounds - final Bounds b = calculateBounds(); gl.glRotated(-p.getPitch() * (180.0 / Math.PI), 0, 0, 1); gl.glRotated(p.getYaw() * (180.0 / Math.PI), 0, 1, 0); gl.glRotated(p.getRoll() * (180.0 / Math.PI), 1, 0, 0); + // Center the rocket in the view. - gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0); + final BoundingBox b = configuration.getBoundingBox(); + gl.glTranslated((b.min.x - b.max.x) / 2.0, 0, 0); } } diff --git a/swing/src/net/sf/openrocket/gui/figureelements/RocketInfo.java b/swing/src/net/sf/openrocket/gui/figureelements/RocketInfo.java index 212d50ef5..70d098089 100644 --- a/swing/src/net/sf/openrocket/gui/figureelements/RocketInfo.java +++ b/swing/src/net/sf/openrocket/gui/figureelements/RocketInfo.java @@ -61,10 +61,6 @@ public class RocketInfo implements FigureElement { private float line = 0; private float x1, x2, y1, y2; - - - - public RocketInfo(FlightConfiguration configuration) { this.configuration = configuration; this.stabilityUnits = UnitGroup.stabilityUnits(configuration); diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java index 5775390a1..700426068 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java @@ -14,7 +14,6 @@ import java.awt.geom.Ellipse2D; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; -import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.Map.Entry; @@ -34,6 +33,7 @@ import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.ArrayList; import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.Coordinate; diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java index 33a014531..eb534701c 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java @@ -67,12 +67,12 @@ import net.sf.openrocket.simulation.listeners.SimulationListener; import net.sf.openrocket.simulation.listeners.system.ApogeeEndListener; import net.sf.openrocket.simulation.listeners.system.InterruptListener; import net.sf.openrocket.startup.Application; -import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.util.ChangeSource; import net.sf.openrocket.util.Chars; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.StateChangeListener; +import net.sf.openrocket.unit.UnitGroup; /** @@ -607,18 +607,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change figure3d.setCP(cp); // Length bound is assumed to be tight - double length = 0; - Collection bounds = curConfig.getBounds(); - if (!bounds.isEmpty()) { - double minX = Double.POSITIVE_INFINITY, maxX = Double.NEGATIVE_INFINITY; - for (Coordinate c : bounds) { - if (c.x < minX) - minX = c.x; - if (c.x > maxX) - maxX = c.x; - } - length = maxX - minX; - } + double length = curConfig.getLength(); double diameter = Double.NaN; for (RocketComponent c : curConfig.getCoreComponents()) {