diff --git a/core/src/net/sf/openrocket/rocketcomponent/MassObject.java b/core/src/net/sf/openrocket/rocketcomponent/MassObject.java index 80ac7c2b6..58adc3f39 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/MassObject.java +++ b/core/src/net/sf/openrocket/rocketcomponent/MassObject.java @@ -66,12 +66,12 @@ public abstract class MassObject extends InternalComponent { } - public final double getRadius() { + public double getRadius() { return radius; } - public final void setRadius(double radius) { + public void setRadius(double radius) { radius = Math.max(radius, 0); for (RocketComponent listener : configListeners) { diff --git a/core/src/net/sf/openrocket/rocketcomponent/Parachute.java b/core/src/net/sf/openrocket/rocketcomponent/Parachute.java index 74ffc5f08..e7b2a12c7 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Parachute.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Parachute.java @@ -15,6 +15,7 @@ public class Parachute extends RecoveryDevice { private double diameter; private final double InitialPackedLength = this.length; private final double InitialPackedRadius = this.radius; + private boolean autoRadius; private Material lineMaterial; private int lineCount = 6; @@ -145,6 +146,64 @@ public class Parachute extends RecoveryDevice { //// Parachute return trans.get("Parachute.Parachute"); } + + @Override + public void setRadius(double radius) { + radius = Math.max(radius, 0); + + for (RocketComponent listener : configListeners) { + if (listener instanceof MassObject) { + ((MassObject) listener).setRadius(radius); + } + } + + if (MathUtil.equals(this.radius, radius) && (!autoRadius)) + return; + + this.autoRadius = false; + this.radius = radius; + fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + } + + @Override + public double getRadius() { + if (autoRadius) { + if (parent == null) { + return radius; + } + if (parent instanceof NoseCone) { + return ((NoseCone) parent).getAftRadius(); + } else if (parent instanceof Transition) { + double foreRadius = ((Transition) parent).getForeRadius(); + double aftRadius = ((Transition) parent).getAftRadius(); + return (Math.max(foreRadius, aftRadius)); + } else if (parent instanceof BodyComponent) { + return ((BodyComponent) parent).getInnerRadius(); + } else if (parent instanceof RingComponent) { + return ((RingComponent) parent).getInnerRadius(); + } + } + return radius; + } + + public boolean isRadiusAutomatic() { + return autoRadius; + } + + public void setRadiusAutomatic(boolean auto) { + for (RocketComponent listener : configListeners) { + if (listener instanceof Parachute) { + ((Parachute) listener).setRadiusAutomatic(auto); + } + } + + if (autoRadius == auto) + return; + + autoRadius = auto; + + fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + } @Override public boolean allowsChildren() { @@ -223,26 +282,9 @@ public class Parachute extends RecoveryDevice { //// END Implement parachute packed diameter //// BEGIN Size parachute packed diameter within parent inner diameter if (length > 0 && radius > 0) { - double parachuteVolume; - double trimPackedRadius = .975; - parachuteVolume = (Math.PI * Math.pow(radius, 2) * length); - - if (parent instanceof NoseCone) { - radius = ((NoseCone) parent).getAftRadius(); - length = parachuteVolume / (Math.PI * Math.pow((radius), 2)); - } else if (parent instanceof Transition) { - double foreRadius = ((Transition) parent).getForeRadius(); - double aftRadius = ((Transition) parent).getAftRadius(); - double innerRadius = (Math.max(foreRadius, aftRadius)); - radius = innerRadius * Math.pow((trimPackedRadius), 2); - length = parachuteVolume / (Math.PI * Math.pow((radius), 2)); - } else if (parent instanceof BodyComponent) { - radius = ((BodyComponent) parent).getInnerRadius(); - length = parachuteVolume / (Math.PI * Math.pow((radius), 2)); - } else if (parent instanceof RingComponent) { - radius = ((RingComponent) parent).getInnerRadius(); - length = parachuteVolume / (Math.PI * Math.pow((radius), 2)); - } + double parachuteVolume = (Math.PI * Math.pow(radius, 2) * length); + setRadiusAutomatic(true); + length = parachuteVolume / (Math.PI * Math.pow(getRadius(), 2)); } //// END Size parachute packed diameter within parent inner diameter diff --git a/swing/src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java index fac72e6fa..dcbcf9ad2 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java @@ -6,6 +6,7 @@ import java.awt.event.ActionListener; import javax.swing.ComboBoxModel; import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; @@ -30,6 +31,7 @@ import net.sf.openrocket.rocketcomponent.DeploymentConfiguration; import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent; import net.sf.openrocket.rocketcomponent.Parachute; import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.rocketcomponent.Transition; import net.sf.openrocket.rocketcomponent.position.AxialMethod; import net.sf.openrocket.startup.Application; import net.sf.openrocket.unit.UnitGroup; @@ -177,7 +179,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { //// Packed diameter: panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Packeddiam"))); - DoubleModel od = new DoubleModel(component, "Radius", 2, UnitGroup.UNITS_LENGTH, 0); + final DoubleModel od = new DoubleModel(component, "Radius", 2, UnitGroup.UNITS_LENGTH, 0); // Diameter = 2*Radius spin = new JSpinner(od.getSpinnerModel()); @@ -185,7 +187,12 @@ public class ParachuteConfig extends RecoveryDeviceConfig { panel.add(spin, "growx"); panel.add(new UnitSelector(od), "growx"); - panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 30lp"); + panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap"); + + ////// Automatic + JCheckBox checkAutoPackedRadius = new JCheckBox(od.getAutomaticAction()); + checkAutoPackedRadius.setText(trans.get("TransitionCfg.checkbox.Automatic")); + panel.add(checkAutoPackedRadius, "skip, span 2, wrap 30lp"); //// Deployment