From 96cfeb775a089a5a6f45526138155cd4cc49de9d Mon Sep 17 00:00:00 2001 From: Misha Turnbull Date: Mon, 28 Jan 2019 16:39:57 -0600 Subject: [PATCH 01/10] Add first half of nozzle config Signed-off-by: Misha Turnbull --- .../gui/configdialog/EngineNozzleConfig.java | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java diff --git a/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java new file mode 100644 index 0000000000..89bf4a3463 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java @@ -0,0 +1,123 @@ +package net.sf.openrocket.gui.configdialog; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSpinner; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.BooleanModel; +import net.sf.openrocket.gui.adaptors.DoubleModel; +import net.sf.openrocket.gui.components.BasicSlider; +import net.sf.openrocket.gui.components.DescriptionArea; +import net.sf.openrocket.gui.components.UnitSelector; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.material.Material; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.rocketcomponent.EngineNozzle; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.UnitGroup; + +public class EngineNozzleConfig extends RocketComponentConfig { + + private static final Translator trans = Application.getTranslator(); + private JComboBox typeBox; + private JLabel shapeLabel; + private JSpinner shapeSpinner; + private BasicSlider shapeSlider; + private DescriptionArea description; + private static final String PREDESC = ""; // ??? + + public EngineNozzleConfig(OpenRocketDocument d, RocketComponent c) { + super(d, c); + + final JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", "")); + + panel.add(new JLabel(trans.get("EngineNozzle.lbl.shape"))); + + EngineNozzle.Shape selected = ((EngineNozzle) component).getType(); + EngineNozzle.Shape[] typeList = EngineNozzle.Shape.values(); + + typeBox = new JComboBox(typeList); + typeBox.setEditable(false); + typeBox.setSelectedItem(selected); + typeBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + EngineNozzle.Shape s = (EngineNozzle.Shape) typeBox.getSelectedItem(); + ((EngineNozzle) component).setType(s); + description.setText(PREDESC + s.getTransitionDescription()); + updateEnabled(); + } + }); + panel.add(typeBox, "span, split 2"); + + { + final JCheckBox checkbox = new JCheckBox(new BooleanModel(component, "Clipped")); + checkbox.setText(trans.get("EngineNozzle.lbl.Clipped")); + panel.add(checkbox, "wrap"); + + // shape parameter + this.shapeLabel = new JLabel(trans.get("EngineNozzle.lbl.Shapeparam")); + panel.add(shapeLabel); + updateEnabled(); + } + + { + final DoubleModel shapeModel = new DoubleModel(component, "ShapeParameter"); + this.shapeSpinner = new JSpinner(shapeModel.getSpinnerModel()); + panel.add(shapeSpinner, "growx"); + DoubleModel min = new DoubleModel(component, "ShapeParameterMin"); + DoubleModel max = new DoubleModel(component, "ShapeParameterMax"); + this.shapeSlider = new BasicSlider(shapeModel.getSliderModel(min, max)); + panel.add(shapeSlider, "skip, w 100lp, wrap"); + updateEnabled(); + } + + { + panel.add(new JLabel(trans.get("EngineNozzle.lbl.length"))); + final DoubleModel lengthModel = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0); + final JSpinner lengthSpinner = new JSpinner(lengthModel.getSpinnerModel()); + lengthSpinner.setEditor(new SpinnerEditor(lengthSpinner)); + panel.add(lengthSpinner, "growx"); + panel.add(new UnitSelector(lengthModel), "growx"); + panel.add(new BasicSlider(lengthModel.getSliderModel(0, 0.05, 0.3)), "w 100lp, wrap"); + } + + { + panel.add(new JLabel(trans.get("EngineNozzle.lbl.foreDiam"))); + final DoubleModel foreRadiusModel = new DoubleModel(component, "ForeRadius", 2, UnitGroup.UNITS_LENGTH, 0); + final JSpinner foreRadiusSpinner = new JSpinner(foreRadiusModel.getSpinnerModel()); + foreRadiusSpinner.setEditor(new SpinnerEditor(foreRadiusSpinner)); + panel.add(foreRadiusSpinner, "growx"); + panel.add(new UnitSelector(foreRadiusModel), "growx"); + panel.add(new BasicSlider(foreRadiusModel.getSliderModel(0, 0.04, 02)), "w 100lp, wrap 0px"); + + final JCheckBox checkbox = new JCheckBox(foreRadiusModel.getAutomaticAction()); + checkbox.setText(trans.get("EngineNozzle.lbl.automatic")); + panel.add(checkbox, "skip, span 2, wrap"); + } + + { + panel.add(new JLabel(trans.get("EngineNozzle.lbl.aftdiam"))); + final DoubleModel aftRadiusModel = new DoubleModel(component, "AftRadius", 2, UnitGroup.UNITS_LENGTH, 0); + final JSpinner aftRadiusSpinner = new JSpinner(aftRadiusModel.getSpinnerModel()); + aftRadiusSpinner.setEditor(new SpinnerEditor(aftRadiusSpinner)); + panel.add(aftRadiusSpinner, "growx"); + panel.add(new UnitSelector(aftRadiusModel), "growx"); + panel.add(new BasicSlider(aftRadiusModel.getSliderModel(0, 0.04, 0.)), "w 100lp, wrap 0px"); + + final JCheckBox checkbox = new JCheckBox(aftRadiusModel.getAutomaticAction()); + checkbox.setText(trans.get("EngineNozzle.lbl.automatic")); + panel.add(checkbox, "skip, span 2, wrap"); + } + } + + +} From 82ac8a9581b0ee098cd444e4dcd390c1cadfade9 Mon Sep 17 00:00:00 2001 From: Misha Turnbull Date: Tue, 29 Jan 2019 14:14:43 -0600 Subject: [PATCH 02/10] Add updateEnabled method to EngineNozzleConfig GUI Signed-off-by: Misha Turnbull --- .../sf/openrocket/gui/configdialog/EngineNozzleConfig.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java index 89bf4a3463..48c611b72f 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java @@ -119,5 +119,12 @@ public void actionPerformed(ActionEvent e) { } } + private void updateEnabled() { + boolean e = ((EngineNozzle) component).getType().usesParameter(); + shapeLabel.setEnabled(e); + shapeSpinner.setEnabled(e); + shapeSlider.setEnabled(e); + } + } From 929e031e4bb036e69fe4ccd9e834f4d91942c8cf Mon Sep 17 00:00:00 2001 From: Misha Turnbull Date: Tue, 29 Jan 2019 15:10:28 -0600 Subject: [PATCH 03/10] Finish Engine Nozzle Config GUI Signed-off-by: Misha Turnbull --- .../rocketcomponent/EngineNozzle.java | 8 +++--- .../gui/configdialog/EngineNozzleConfig.java | 27 ++++++++++++++++++- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/EngineNozzle.java b/core/src/net/sf/openrocket/rocketcomponent/EngineNozzle.java index a518ce6fa5..429d7f0c11 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/EngineNozzle.java +++ b/core/src/net/sf/openrocket/rocketcomponent/EngineNozzle.java @@ -539,7 +539,7 @@ public double getRadius(double x, double radius, double length, double param) { // Privete fields of the shapes private final String name; - private final String transitionDesc; + private final String engineNozzleDesc; private final String noseconeDesc; private final boolean canClip; @@ -553,7 +553,7 @@ public double getRadius(double x, double radius, double length, double param) { this.name = name; this.canClip = canClip; this.noseconeDesc = noseconeDesc; - this.transitionDesc = transitionDesc; + this.engineNozzleDesc = transitionDesc; } @@ -567,8 +567,8 @@ public String getName() { /** * Get a description of the Transition shape. */ - public String getTransitionDescription() { - return transitionDesc; + public String getEngineNozzleDescription() { + return engineNozzleDesc; } /** diff --git a/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java index 48c611b72f..92a6246dcc 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java @@ -52,7 +52,7 @@ public EngineNozzleConfig(OpenRocketDocument d, RocketComponent c) { public void actionPerformed(ActionEvent e) { EngineNozzle.Shape s = (EngineNozzle.Shape) typeBox.getSelectedItem(); ((EngineNozzle) component).setType(s); - description.setText(PREDESC + s.getTransitionDescription()); + description.setText(PREDESC + s.getEngineNozzleDescription()); updateEnabled(); } }); @@ -117,6 +117,31 @@ public void actionPerformed(ActionEvent e) { checkbox.setText(trans.get("EngineNozzle.lbl.automatic")); panel.add(checkbox, "skip, span 2, wrap"); } + + { + panel.add(new JLabel(trans.get("EngineNozzle.lbl.wallthick"))); + final DoubleModel thickModel = new DoubleModel(component, "Thickness", UnitGroup.UNITS_LENGTH, 0); + final JSpinner thickSpinner = new JSpinner(thickModel.getSpinnerModel()); + thickSpinner.setEditor(new SpinnerEditor(thickSpinner)); + panel.add(thickSpinner, "growx"); + panel.add(new UnitSelector(thickModel), "growx"); + panel.add(new BasicSlider(thickModel.getSliderModel(0, 0.01)), "w 100lp, wrap 0px"); + } + + JPanel panel2 = new JPanel(new MigLayout("ins 0")); + description = new DescriptionArea(5); + description.setText(PREDESC + ((EngineNozzle) component).getType().getEngineNozzleDescription()); + panel2.add(description, "wmin 250lp, spanx, grpwx, wrap para"); + + panel2.add(materialPanel(Material.Type.BULK), "span, wrap"); + panel.add(panel2, "cell 4 0, gapleft paragrap, alighy 0%, spany"); + + // tabs + tabbedPane.insertTab(trans.get("EngineNozzle.tab.General"), null, panel, + trans.get("EngineNozzle.lbl.Generalproperties"), 0); + tabbedPane.insertTab(trans.get("TransitionCfg.tab.Shoulder"), null, shoulderTab(), + trans.get("TransitionCfg.tab.Shoulderproperties"), 1); + tabbedPane.setSelectedIndex(0); } private void updateEnabled() { From 27b2a748379953b51a7c5d7c4f8a07c95b2b2fe7 Mon Sep 17 00:00:00 2001 From: Misha Turnbull Date: Tue, 29 Jan 2019 15:26:52 -0600 Subject: [PATCH 04/10] Add EngineNozzle button to main GUI Signed-off-by: Misha Turnbull --- core/resources/l10n/messages.properties | 11 +++++++ .../gui/main/ComponentAddButtons.java | 30 +++---------------- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 90b271386f..3083ffdbdd 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -1482,6 +1482,17 @@ FuelTank.tab.General = Fuel Tank FuelTank.tab.ttip.General = Fuel settings ! Engine Nozzle Nozzle.Nozzle = Engine Nozzle +EngineNozzle.lbl.shape = Nozzle Shape +EngineNozzle.lbl.Clipped = Clipped +EngineNozzle.lbl.Shapeparam = Shape parameter +EngineNozzle.lbl.length = Length +EngineNozzle.lbl.foreDiam = Fore Diameter +EngineNozzle.lbl.aftdiam = Aft Diameter +EngineNozzle.lbl.automatic = Automatic +EngineNozzle.lbl.wallthick = Wall thickness +EngineNozzle.lbl.tab.General = General +EngineNozzle.lbl.Generalproperties = General Properties +compaddbuttons.Enginenozzle = Engine Nozzle ! Parachute Parachute.Parachute = Parachute ! ShockCord diff --git a/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java b/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java index a87255c1dc..e3985da22d 100644 --- a/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java +++ b/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java @@ -25,6 +25,7 @@ import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; +import net.sf.openrocket.rocketcomponent.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,31 +36,6 @@ import net.sf.openrocket.gui.main.componenttree.ComponentTreeModel; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.logging.Markers; -import net.sf.openrocket.rocketcomponent.AxialStage; -import net.sf.openrocket.rocketcomponent.BodyComponent; -import net.sf.openrocket.rocketcomponent.BodyTube; -import net.sf.openrocket.rocketcomponent.Bulkhead; -import net.sf.openrocket.rocketcomponent.CenteringRing; -import net.sf.openrocket.rocketcomponent.EllipticalFinSet; -import net.sf.openrocket.rocketcomponent.EngineBlock; -import net.sf.openrocket.rocketcomponent.FreeformFinSet; -import net.sf.openrocket.rocketcomponent.InnerTube; -import net.sf.openrocket.rocketcomponent.LaunchLug; -import net.sf.openrocket.rocketcomponent.MassComponent; -import net.sf.openrocket.rocketcomponent.NoseCone; -import net.sf.openrocket.rocketcomponent.Parachute; -import net.sf.openrocket.rocketcomponent.ParallelStage; -import net.sf.openrocket.rocketcomponent.PodSet; -import net.sf.openrocket.rocketcomponent.RailButton; -import net.sf.openrocket.rocketcomponent.Rocket; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.rocketcomponent.ShockCord; -import net.sf.openrocket.rocketcomponent.Streamer; -import net.sf.openrocket.rocketcomponent.Transition; -import net.sf.openrocket.rocketcomponent.TrapezoidFinSet; -import net.sf.openrocket.rocketcomponent.TubeCoupler; -import net.sf.openrocket.rocketcomponent.TubeFinSet; -import net.sf.openrocket.rocketcomponent.FuelTank; import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Preferences; import net.sf.openrocket.util.BugException; @@ -158,7 +134,9 @@ public ComponentAddButtons(OpenRocketDocument document, TreeSelectionModel model //// Engine\nblock new ComponentButton(EngineBlock.class, trans.get("compaddbuttons.Engineblock")), //// Fuel\ntank - new ComponentButton(FuelTank.class, trans.get("compaddbuttons.Fueltank"))); + new ComponentButton(FuelTank.class, trans.get("compaddbuttons.Fueltank")), + //// Engine\nNozzle + new ComponentButton(EngineNozzle.class, trans.get("compaddbuttons.Enginenozzle"))); row++; From a208b8636b02ef2d6161f2669dded199ccfd512f Mon Sep 17 00:00:00 2001 From: Misha Turnbull Date: Sun, 10 Feb 2019 10:50:51 -0600 Subject: [PATCH 05/10] Revert to JDK 1.8 Signed-off-by: Misha Turnbull --- .idea/misc.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 6f34b5b648..33b4462877 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -46,7 +46,7 @@ - + \ No newline at end of file From 2c8959ebb04d14ffb5b9f2aecc57b7ed1966aff6 Mon Sep 17 00:00:00 2001 From: Misha Turnbull Date: Sun, 10 Feb 2019 11:00:57 -0600 Subject: [PATCH 06/10] Fix engine nozzle not being addable Signed-off-by: Misha Turnbull --- swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java b/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java index e3985da22d..d5bb56ec3f 100644 --- a/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java +++ b/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java @@ -136,7 +136,7 @@ public ComponentAddButtons(OpenRocketDocument document, TreeSelectionModel model //// Fuel\ntank new ComponentButton(FuelTank.class, trans.get("compaddbuttons.Fueltank")), //// Engine\nNozzle - new ComponentButton(EngineNozzle.class, trans.get("compaddbuttons.Enginenozzle"))); + new BodyComponentButton(EngineNozzle.class, trans.get("compaddbuttons.Enginenozzle"))); row++; From aa37d8d60ad1ebe1eccf33e10a05239ea5e9e57c Mon Sep 17 00:00:00 2001 From: Misha Turnbull Date: Sun, 10 Feb 2019 11:23:53 -0600 Subject: [PATCH 07/10] Switch EngineNozzle to inherit from Transition Fixes #10 Signed-off-by: Misha Turnbull --- .../barrowman/SymmetricComponentCalc.java | 7 +- .../rocketcomponent/EngineNozzle.java | 339 +----------------- .../gui/configdialog/EngineNozzleConfig.java | 4 +- 3 files changed, 5 insertions(+), 345 deletions(-) diff --git a/core/src/net/sf/openrocket/aerodynamics/barrowman/SymmetricComponentCalc.java b/core/src/net/sf/openrocket/aerodynamics/barrowman/SymmetricComponentCalc.java index 1bfcfa2ee4..a4eb6058df 100644 --- a/core/src/net/sf/openrocket/aerodynamics/barrowman/SymmetricComponentCalc.java +++ b/core/src/net/sf/openrocket/aerodynamics/barrowman/SymmetricComponentCalc.java @@ -7,10 +7,7 @@ import net.sf.openrocket.aerodynamics.FlightConditions; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.rocketcomponent.BodyTube; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.rocketcomponent.SymmetricComponent; -import net.sf.openrocket.rocketcomponent.Transition; +import net.sf.openrocket.rocketcomponent.*; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.LinearInterpolator; @@ -69,7 +66,7 @@ public SymmetricComponentCalc(RocketComponent c) { shape = ((Transition) component).getType(); param = ((Transition) component).getShapeParameter(); frontalArea = Math.abs(Math.PI * (foreRadius * foreRadius - aftRadius * aftRadius)); - + double r = component.getRadius(0.99 * length); sinphi = (aftRadius - r) / MathUtil.hypot(aftRadius - r, 0.01 * length); } else { diff --git a/core/src/net/sf/openrocket/rocketcomponent/EngineNozzle.java b/core/src/net/sf/openrocket/rocketcomponent/EngineNozzle.java index 429d7f0c11..49b94b05dd 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/EngineNozzle.java +++ b/core/src/net/sf/openrocket/rocketcomponent/EngineNozzle.java @@ -11,7 +11,7 @@ import static net.sf.openrocket.util.MathUtil.pow2; import static net.sf.openrocket.util.MathUtil.pow3; -public class EngineNozzle extends SymmetricComponent { +public class EngineNozzle extends Transition { private static Translator trans = Application.getTranslator(); private static final double CLIP_PRECISION = 0.0001; @@ -272,8 +272,6 @@ public void setForeShoulderCapped(boolean capped) { } - - public double getAftShoulderRadius() { return aftShoulderRadius; } @@ -320,341 +318,6 @@ public void setAftShoulderCapped(boolean capped) { } ///////////////////////// End Getters & Setters - public static enum Shape { - - /** - * Conical shape. - */ - //// Conical - CONICAL(trans.get("Shape.Conical"), - //// A conical nose cone has a profile of a triangle. - trans.get("Shape.Conical.desc1"), - //// A conical transition has straight sides. - trans.get("Shape.Conical.desc2")) { - @Override - public double getRadius(double x, double radius, double length, double param) { - assert x >= 0; - assert x <= length; - assert radius >= 0; - return radius * x / length; - } - }, - - /** - * Ogive shape. The shape parameter is the portion of an extended tangent ogive - * that will be used. That is, for param==1 a tangent ogive will be produced, and - * for smaller values the shape straightens out into a cone at param==0. - */ - //// Ogive - OGIVE(trans.get("Shape.Ogive"), - //// An ogive nose cone has a profile that is a segment of a circle. The shape parameter value 1 produces a tangent ogive, which has a smooth transition to the body tube, values less than 1 produce secant ogives. - trans.get("Shape.Ogive.desc1"), - //// An ogive transition has a profile that is a segment of a circle. The shape parameter value 1 produces a tangent ogive, which has a smooth transition to the body tube at the aft end, values less than 1 produce secant ogives. - trans.get("Shape.Ogive.desc2")) { - @Override - public boolean usesParameter() { - return true; // Range 0...1 is default - } - - @Override - public double defaultParameter() { - return 1.0; // Tangent ogive by default - } - - @Override - public double getRadius(double x, double radius, double length, double param) { - assert x >= 0; - assert x <= length; - assert radius >= 0; - assert param >= 0; - assert param <= 1; - - // Impossible to calculate ogive for length < radius, scale instead - // TODO: LOW: secant ogive could be calculated lower - if (length < radius) { - x = x * radius / length; - length = radius; - } - - if (param < 0.001) - return CONICAL.getRadius(x, radius, length, param); - - // Radius of circle is: - double R = MathUtil.safeSqrt((pow2(length) + pow2(radius)) * - (pow2((2 - param) * length) + pow2(param * radius)) / (4 * pow2(param * radius))); - double L = length / param; - // double R = (radius + length*length/(radius*param*param))/2; - double y0 = MathUtil.safeSqrt(R * R - L * L); - return MathUtil.safeSqrt(R * R - (L - x) * (L - x)) - y0; - } - }, - - /** - * Ellipsoidal shape. - */ - //// Ellipsoid - ELLIPSOID(trans.get("Shape.Ellipsoid"), - //// An ellipsoidal nose cone has a profile of a half-ellipse with major axes of lengths 2×Length and Diameter. - trans.get("Shape.Ellipsoid.desc1"), - //// An ellipsoidal transition has a profile of a half-ellipse with major axes of lengths 2×Length and Diameter. If the transition is not clipped, then the profile is extended at the center by the corresponding radius. - trans.get("Shape.Ellipsoid.desc2"), true) { - @Override - public double getRadius(double x, double radius, double length, double param) { - assert x >= 0; - assert x <= length; - assert radius >= 0; - x = x * radius / length; - return MathUtil.safeSqrt(2 * radius * x - x * x); // radius/length * sphere - } - }, - - //// Power series - POWER(trans.get("Shape.Powerseries"), - trans.get("Shape.Powerseries.desc1"), - trans.get("Shape.Powerseries.desc2"), true) { - @Override - public boolean usesParameter() { // Range 0...1 - return true; - } - - @Override - public double defaultParameter() { - return 0.5; - } - - @Override - public double getRadius(double x, double radius, double length, double param) { - assert x >= 0; - assert x <= length; - assert radius >= 0; - assert param >= 0; - assert param <= 1; - if (param <= 0.00001) { - if (x <= 0.00001) - return 0; - else - return radius; - } - return radius * Math.pow(x / length, param); - } - - }, - - //// Parabolic series - PARABOLIC(trans.get("Shape.Parabolicseries"), - ////A parabolic series nose cone has a profile of a parabola. The shape parameter defines the segment of the parabola to utilize. The shape parameter 1.0 produces a full parabola which is tangent to the body tube, 0.75 produces a 3/4 parabola, 0.5 procudes a 1/2 parabola and 0 produces a conical nose cone. - trans.get("Shape.Parabolicseries.desc1"), - ////A parabolic series transition has a profile of a parabola. The shape parameter defines the segment of the parabola to utilize. The shape parameter 1.0 produces a full parabola which is tangent to the body tube at the aft end, 0.75 produces a 3/4 parabola, 0.5 procudes a 1/2 parabola and 0 produces a conical transition. - trans.get("Shape.Parabolicseries.desc2")) { - - // In principle a parabolic transition is clippable, but the difference is - // negligible. - - @Override - public boolean usesParameter() { // Range 0...1 - return true; - } - - @Override - public double defaultParameter() { - return 1.0; - } - - @Override - public double getRadius(double x, double radius, double length, double param) { - assert x >= 0; - assert x <= length; - assert radius >= 0; - assert param >= 0; - assert param <= 1; - - return radius * ((2 * x / length - param * pow2(x / length)) / (2 - param)); - } - }, - - //// Haack series - HAACK(trans.get("Shape.Haackseries"), - //// The Haack series nose cones are designed to minimize drag. The shape parameter 0 produces an LD-Haack or Von Karman nose cone, which minimizes drag for fixed length and diameter, while a value of 0.333 produces an LV-Haack nose cone, which minimizes drag for fixed length and volume. - trans.get("Shape.Haackseries.desc1"), - //// The Haack series nose cones are designed to minimize drag. These transition shapes are their equivalents, but do not necessarily produce optimal drag for transitions. The shape parameter 0 produces an LD-Haack or Von Karman shape, while a value of 0.333 produces an LV-Haack shape. - trans.get("Shape.Haackseries.desc2"), true) { - - @Override - public boolean usesParameter() { - return true; - } - - @Override - public double maxParameter() { - return 1.0 / 3.0; // Range 0...1/3 - } - - @Override - public double getRadius(double x, double radius, double length, double param) { - assert x >= 0; - assert x <= length; - assert radius >= 0; - assert param >= 0; - assert param <= 2; - - double theta = Math.acos(1 - 2 * x / length); - if (MathUtil.equals(param, 0)) { - return radius * MathUtil.safeSqrt((theta - sin(2 * theta) / 2) / Math.PI); - } - return radius * MathUtil.safeSqrt((theta - sin(2 * theta) / 2 + param * pow3(sin(theta))) / Math.PI); - } - }, - - // POLYNOMIAL("Smooth polynomial", - // "A polynomial is fitted such that the nose cone profile is horizontal "+ - // "at the aft end of the transition. The angle at the tip is defined by "+ - // "the shape parameter.", - // "A polynomial is fitted such that the transition profile is horizontal "+ - // "at the aft end of the transition. The angle at the fore end is defined "+ - // "by the shape parameter.") { - // @Override - // public boolean usesParameter() { - // return true; - // } - // @Override - // public double maxParameter() { - // return 3.0; // Range 0...3 - // } - // @Override - // public double defaultParameter() { - // return 0.0; - // } - // public double getRadius(double x, double radius, double length, double param) { - // assert x >= 0; - // assert x <= length; - // assert radius >= 0; - // assert param >= 0; - // assert param <= 3; - // // p(x) = (k-2)x^3 + (3-2k)x^2 + k*x - // x = x/length; - // return radius*((((param-2)*x + (3-2*param))*x + param)*x); - // } - // } - ; - - // Privete fields of the shapes - private final String name; - private final String engineNozzleDesc; - private final String noseconeDesc; - private final boolean canClip; - - // Non-clippable constructor - Shape(String name, String noseconeDesc, String transitionDesc) { - this(name, noseconeDesc, transitionDesc, false); - } - - // Clippable constructor - Shape(String name, String noseconeDesc, String transitionDesc, boolean canClip) { - this.name = name; - this.canClip = canClip; - this.noseconeDesc = noseconeDesc; - this.engineNozzleDesc = transitionDesc; - } - - - /** - * Return the name of the transition shape name. - */ - public String getName() { - return name; - } - - /** - * Get a description of the Transition shape. - */ - public String getEngineNozzleDescription() { - return engineNozzleDesc; - } - - /** - * Get a description of the NoseCone shape. - */ - public String getNoseConeDescription() { - return noseconeDesc; - } - - /** - * Check whether the shape differs in clipped mode. The clipping should be - * enabled by default if possible. - */ - public boolean isClippable() { - return canClip; - } - - /** - * Return whether the shape uses the shape parameter. (Default false.) - */ - public boolean usesParameter() { - return false; - } - - /** - * Return the minimum value of the shape parameter. (Default 0.) - */ - public double minParameter() { - return 0.0; - } - - /** - * Return the maximum value of the shape parameter. (Default 1.) - */ - public double maxParameter() { - return 1.0; - } - - /** - * Return the default value of the shape parameter. (Default 0.) - */ - public double defaultParameter() { - return 0.0; - } - - /** - * Calculate the basic radius of a transition with the given radius, length and - * shape parameter at the point x from the tip of the component. It is assumed - * that the fore radius if zero and the aft radius is radius >= 0. - * Boattails are achieved by reversing the component. - * - * @param x Position from the tip of the component. - * @param radius Aft end radius >= 0. - * @param length Length of the transition >= 0. - * @param param Valid shape parameter. - * @return The basic radius at the given position. - */ - public abstract double getRadius(double x, double radius, double length, double param); - - - /** - * Returns the name of the shape (same as getName()). - */ - @Override - public String toString() { - return name; - } - - /** - * Lookup the Shape given the localized name. This differs from the standard valueOf as that looks up - * based on the canonical name, not the localized name which is an instance var. - * - * @param localizedName - * @return - */ - public static Shape toShape(String localizedName) { - Shape[] values = Shape.values(); - for (Shape value : values) { - if (value.getName().equals(localizedName)) { - return value; - } - } - return null; - } - } - /** * Numerically solve clipLength from the equation * r1 == type.getRadius(clipLength,r2,clipLength+length) diff --git a/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java index 92a6246dcc..137d6df156 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java @@ -52,7 +52,7 @@ public EngineNozzleConfig(OpenRocketDocument d, RocketComponent c) { public void actionPerformed(ActionEvent e) { EngineNozzle.Shape s = (EngineNozzle.Shape) typeBox.getSelectedItem(); ((EngineNozzle) component).setType(s); - description.setText(PREDESC + s.getEngineNozzleDescription()); + description.setText(PREDESC + s.getTransitionDescription()); updateEnabled(); } }); @@ -130,7 +130,7 @@ public void actionPerformed(ActionEvent e) { JPanel panel2 = new JPanel(new MigLayout("ins 0")); description = new DescriptionArea(5); - description.setText(PREDESC + ((EngineNozzle) component).getType().getEngineNozzleDescription()); + description.setText(PREDESC + ((EngineNozzle) component).getType().getTransitionDescription()); panel2.add(description, "wmin 250lp, spanx, grpwx, wrap para"); panel2.add(materialPanel(Material.Type.BULK), "span, wrap"); From 52b42e27c4d433101d42b5987ad39a1ac6bc93c0 Mon Sep 17 00:00:00 2001 From: Misha Turnbull Date: Sun, 10 Feb 2019 11:45:11 -0600 Subject: [PATCH 08/10] Fix multiple typos Also fix #11 by doing this Signed-off-by: Misha Turnbull --- core/resources/l10n/messages.properties | 2 +- .../gui/configdialog/EngineNozzleConfig.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 3083ffdbdd..7e53c5eeda 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -1490,7 +1490,7 @@ EngineNozzle.lbl.foreDiam = Fore Diameter EngineNozzle.lbl.aftdiam = Aft Diameter EngineNozzle.lbl.automatic = Automatic EngineNozzle.lbl.wallthick = Wall thickness -EngineNozzle.lbl.tab.General = General +EngineNozzle.tab.General = General EngineNozzle.lbl.Generalproperties = General Properties compaddbuttons.Enginenozzle = Engine Nozzle ! Parachute diff --git a/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java index 137d6df156..ca793f9c08 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/EngineNozzleConfig.java @@ -66,7 +66,7 @@ public void actionPerformed(ActionEvent e) { // shape parameter this.shapeLabel = new JLabel(trans.get("EngineNozzle.lbl.Shapeparam")); panel.add(shapeLabel); - updateEnabled(); + //updateEnabled(); } { @@ -97,7 +97,7 @@ public void actionPerformed(ActionEvent e) { foreRadiusSpinner.setEditor(new SpinnerEditor(foreRadiusSpinner)); panel.add(foreRadiusSpinner, "growx"); panel.add(new UnitSelector(foreRadiusModel), "growx"); - panel.add(new BasicSlider(foreRadiusModel.getSliderModel(0, 0.04, 02)), "w 100lp, wrap 0px"); + panel.add(new BasicSlider(foreRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px"); final JCheckBox checkbox = new JCheckBox(foreRadiusModel.getAutomaticAction()); checkbox.setText(trans.get("EngineNozzle.lbl.automatic")); @@ -111,7 +111,7 @@ public void actionPerformed(ActionEvent e) { aftRadiusSpinner.setEditor(new SpinnerEditor(aftRadiusSpinner)); panel.add(aftRadiusSpinner, "growx"); panel.add(new UnitSelector(aftRadiusModel), "growx"); - panel.add(new BasicSlider(aftRadiusModel.getSliderModel(0, 0.04, 0.)), "w 100lp, wrap 0px"); + panel.add(new BasicSlider(aftRadiusModel.getSliderModel(0, 0.04, 0.5)), "w 100lp, wrap 0px"); final JCheckBox checkbox = new JCheckBox(aftRadiusModel.getAutomaticAction()); checkbox.setText(trans.get("EngineNozzle.lbl.automatic")); @@ -131,10 +131,10 @@ public void actionPerformed(ActionEvent e) { JPanel panel2 = new JPanel(new MigLayout("ins 0")); description = new DescriptionArea(5); description.setText(PREDESC + ((EngineNozzle) component).getType().getTransitionDescription()); - panel2.add(description, "wmin 250lp, spanx, grpwx, wrap para"); + panel2.add(description, "wmin 250lp, spanx, growx, wrap para"); panel2.add(materialPanel(Material.Type.BULK), "span, wrap"); - panel.add(panel2, "cell 4 0, gapleft paragrap, alighy 0%, spany"); + panel.add(panel2, "cell 4 0, gapleft paragraph, aligny 0%, spany"); // tabs tabbedPane.insertTab(trans.get("EngineNozzle.tab.General"), null, panel, From 32fb84bf75f9c41cbc52472f6e538ff22a427976 Mon Sep 17 00:00:00 2001 From: Misha Turnbull Date: Sun, 10 Feb 2019 12:28:49 -0600 Subject: [PATCH 09/10] Allow saving & loading of engine nozzles Signed-off-by: Misha Turnbull --- .../openrocket/importt/DocumentConfig.java | 4 +++ .../openrocket/savers/EngineNozzleSaver.java | 26 +++++++++++++++++++ .../rocketcomponent/EngineNozzle.java | 6 ++--- 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 core/src/net/sf/openrocket/file/openrocket/savers/EngineNozzleSaver.java diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java index 8393737f62..22e4feafcc 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java @@ -41,6 +41,7 @@ class DocumentConfig { constructors.put("tubefinset", TubeFinSet.class.getConstructor(new Class[0])); constructors.put("launchlug", LaunchLug.class.getConstructor(new Class[0])); constructors.put("railbutton", RailButton.class.getConstructor(new Class[0])); + constructors.put("enginenozzle", EngineNozzle.class.getConstructor(new Class[0])); // Internal components constructors.put("engineblock", EngineBlock.class.getConstructor(new Class[0])); @@ -201,6 +202,9 @@ class DocumentConfig { setters.put("NoseCone:foreshoulderlength", null); setters.put("NoseCone:foreshoulderthickness", null); setters.put("NoseCone:foreshouldercapped", null); + + // Engine Nozzle -- pretty much just transition? + // Is anything needed here?? // FinSet setters.put("FinSet:fincount", new IntSetter( diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/EngineNozzleSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/EngineNozzleSaver.java new file mode 100644 index 0000000000..9df4ee7170 --- /dev/null +++ b/core/src/net/sf/openrocket/file/openrocket/savers/EngineNozzleSaver.java @@ -0,0 +1,26 @@ +package net.sf.openrocket.file.openrocket.savers; + +import java.util.ArrayList; +import java.util.List; + +public class EngineNozzleSaver extends TransitionSaver { + + private static final EngineNozzleSaver instance = new EngineNozzleSaver(); + + public ArrayList getElements(net.sf.openrocket.rocketcomponent.EngineNozzle c) { + ArrayList list = new ArrayList(); + + list.add(""); + instance.addParams(c, list); + list.add(""); + + return list; + } + + @Override + protected void addParams(net.sf.openrocket.rocketcomponent.RocketComponent c, List elements) { + super.addParams(c, elements); + + } + +} diff --git a/core/src/net/sf/openrocket/rocketcomponent/EngineNozzle.java b/core/src/net/sf/openrocket/rocketcomponent/EngineNozzle.java index 49b94b05dd..f16f7b9f8c 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/EngineNozzle.java +++ b/core/src/net/sf/openrocket/rocketcomponent/EngineNozzle.java @@ -35,10 +35,10 @@ public EngineNozzle() { this.foreRadius = DEFAULT_RADIUS; this.aftRadius = DEFAULT_RADIUS; this.length = DEFAULT_RADIUS * 3; - this.autoForeRadius = true; + this.autoForeRadius = false; this.autoAftRadius = true; - this.type = Shape.CONICAL; - this.shapeParameter = 0; + this.type = Shape.PARABOLIC; + this.shapeParameter = 1; this.clipped = true; } From 99ac9d3b57bbac88995951ae9e04034299d26f6e Mon Sep 17 00:00:00 2001 From: Misha Turnbull Date: Sun, 24 Feb 2019 16:01:10 -0600 Subject: [PATCH 10/10] reformatting Signed-off-by: Misha Turnbull --- .../sf/openrocket/file/openrocket/savers/TransitionSaver.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/TransitionSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/TransitionSaver.java index 0a4169f9e1..5900901509 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/TransitionSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/TransitionSaver.java @@ -8,7 +8,8 @@ import net.sf.openrocket.rocketcomponent.Transition; -public class TransitionSaver extends SymmetricComponentSaver { +public class +TransitionSaver extends SymmetricComponentSaver { private static final TransitionSaver instance = new TransitionSaver();