diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties
index 6bb9d119f..d124867cf 100644
--- a/core/resources/l10n/messages.properties
+++ b/core/resources/l10n/messages.properties
@@ -366,12 +366,17 @@ simedtdlg.lbl.ttip.Altitude = The launch altitude above mean sea level.
Checking this box makes the launch rod point into the wind.
+simedtdlg.checkbox.ttip.Intowind2 = A zero launchrod angle will point directly up.
+simedtdlg.checkbox.ttip.Intowind3 = A negative launchrod angle will launch with the wind.
If you uncheck this box you can point the launchrod any direction you please.
+simedtdlg.checkbox.ttip.Intowind4 = If you uncheck this box you can point the launchrod any direction you please.
simedtdlg.lbl.Angle = Angle:
-simedtdlg.lbl.ttip.Angle = The angle of the launch rod from vertical.
+simedtdlg.lbl.ttip.Angle = The angle of the launch rod from vertical.
Positive angles point upwind.
simedtdlg.lbl.Direction = Direction:
simedtdlg.lbl.ttip.Direction1 = Direction of the launch rod relative to the wind.
-simedtdlg.lbl.ttip.Direction2 = = towards the wind,
-simedtdlg.lbl.ttip.Direction3 = = downwind.
+simedtdlg.lbl.ttip.Direction2 = -
+simedtdlg.lbl.ttip.Direction3 = 0 is North.
simedtdlg.border.Simopt = Simulator options
simedtdlg.lbl.Calcmethod = Calculation method:
simedtdlg.lbl.ttip.Calcmethod = The Extended Barrowman method calculates aerodynamic forces according
to the Barrowman equations extended to accommodate more components.
@@ -1485,8 +1490,8 @@ FlightDataType.TYPE_VELOCITY_Z = Vertical velocity
FlightDataType.TYPE_ACCELERATION_Z = Vertical acceleration
FlightDataType.TYPE_VELOCITY_TOTAL = Total velocity
FlightDataType.TYPE_ACCELERATION_TOTAL = Total acceleration
-FlightDataType.TYPE_POSITION_X = Position East-West
-FlightDataType.TYPE_POSITION_Y = Position North-South
+FlightDataType.TYPE_POSITION_X = Position East of launch
+FlightDataType.TYPE_POSITION_Y = Position North of launch
FlightDataType.TYPE_POSITION_XY = Lateral distance
FlightDataType.TYPE_POSITION_DIRECTION = Lateral direction
FlightDataType.TYPE_VELOCITY_XY = Lateral velocity
diff --git a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java
index a21354f7f..cea1e2a9d 100644
--- a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java
+++ b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java
@@ -431,7 +431,7 @@ public class OpenRocketSaver extends RocketSaver {
writeElement("configid", cond.getMotorConfigurationID());
writeElement("launchrodlength", cond.getLaunchRodLength());
writeElement("launchrodangle", cond.getLaunchRodAngle() * 180.0 / Math.PI);
- writeElement("launchroddirection", cond.getLaunchRodDirection() * 180.0 / Math.PI);
+ writeElement("launchroddirection", cond.getLaunchRodDirection() * 360.0 / (2.0 * Math.PI));
writeElement("windaverage", cond.getWindSpeedAverage());
writeElement("windturbulence", cond.getWindTurbulenceIntensity());
writeElement("launchaltitude", cond.getLaunchAltitude());
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java
index f0cde3a4c..2094b0320 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java
@@ -70,7 +70,7 @@ class SimulationConditionsHandler extends AbstractElementHandler {
if (Double.isNaN(d)) {
warnings.add("Illegal launch rod direction defined, ignoring.");
} else {
- conditions.setLaunchRodDirection(d * Math.PI / 180);
+ conditions.setLaunchRodDirection(d * 2.0 * Math.PI / 360);
}
} else if (element.equals("windaverage")) {
if (Double.isNaN(d)) {
@@ -113,7 +113,7 @@ class SimulationConditionsHandler extends AbstractElementHandler {
} else if (element.equals("atmosphere")) {
atmosphereHandler.storeSettings(conditions, warnings);
} else if (element.equals("timestep")) {
- if (Double.isNaN(d) || d <= 0 ) {
+ if (Double.isNaN(d) || d <= 0) {
warnings.add("Illegal time step defined, ignoring.");
} else {
conditions.setTimeStep(d);
diff --git a/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java b/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java
index 9ddfec972..d431569af 100644
--- a/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java
+++ b/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java
@@ -59,24 +59,24 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
private static final double MIN_TIME_STEP = 0.001;
-
+
private Random random;
-
-
+
+
@Override
public RK4SimulationStatus initialize(SimulationStatus original) {
RK4SimulationStatus status = new RK4SimulationStatus(original);
// Copy the existing warnings
- status.setWarnings( original.getWarnings() );
+ status.setWarnings(original.getWarnings());
SimulationConditions sim = original.getSimulationConditions();
status.setLaunchRodDirection(new Coordinate(
- Math.sin(sim.getLaunchRodAngle()) * Math.cos(sim.getLaunchRodDirection()),
- Math.sin(sim.getLaunchRodAngle()) * Math.sin(sim.getLaunchRodDirection()),
+ Math.sin(sim.getLaunchRodAngle()) * Math.cos(Math.PI / 2.0 - sim.getLaunchRodDirection()),
+ Math.sin(sim.getLaunchRodAngle()) * Math.sin(Math.PI / 2.0 - sim.getLaunchRodDirection()),
Math.cos(sim.getLaunchRodAngle())
));
diff --git a/core/src/net/sf/openrocket/simulation/SimulationConditions.java b/core/src/net/sf/openrocket/simulation/SimulationConditions.java
index 61bad44c6..067417d3b 100644
--- a/core/src/net/sf/openrocket/simulation/SimulationConditions.java
+++ b/core/src/net/sf/openrocket/simulation/SimulationConditions.java
@@ -35,7 +35,7 @@ public class SimulationConditions implements Monitorable, Cloneable {
/** Launch rod angle >= 0, radians from vertical */
private double launchRodAngle = 0;
- /** Launch rod direction, 0 = upwind, PI = downwind. */
+ /** Launch rod direction, 0 = north */
private double launchRodDirection = 0;
// TODO: Depreciate these and use worldCoordinate only.
diff --git a/core/src/net/sf/openrocket/simulation/SimulationOptions.java b/core/src/net/sf/openrocket/simulation/SimulationOptions.java
index bb8bfaf82..ba8110cd7 100644
--- a/core/src/net/sf/openrocket/simulation/SimulationOptions.java
+++ b/core/src/net/sf/openrocket/simulation/SimulationOptions.java
@@ -59,10 +59,12 @@ public class SimulationOptions implements ChangeSource, Cloneable {
private double launchRodLength = 1;
- /** Launch rod angle > 0, radians from vertical */
+ /** Keep launch rod parallel to wind*/
+ private boolean launchIntoWind = true;
+ /** Launch rod angle, |radians|<90 from vertical, positive is upwind, negative is downwind */
private double launchRodAngle = 0;
- /** Launch rod direction, 0 = upwind, PI = downwind. */
+ /** Launch rod direction, 0 = north. */
private double launchRodDirection = 0;
@@ -139,12 +141,20 @@ public class SimulationOptions implements ChangeSource, Cloneable {
}
+ public boolean getLaunchIntoWind() {
+ return launchIntoWind;
+ }
+
+ public void setLaunchIntoWind(boolean i) {
+ launchIntoWind = i;
+ }
+
public double getLaunchRodAngle() {
return launchRodAngle;
}
public void setLaunchRodAngle(double launchRodAngle) {
- launchRodAngle = MathUtil.clamp(launchRodAngle, 0, MAX_LAUNCH_ROD_ANGLE);
+ launchRodAngle = MathUtil.clamp(launchRodAngle, -MAX_LAUNCH_ROD_ANGLE, MAX_LAUNCH_ROD_ANGLE);
if (MathUtil.equals(this.launchRodAngle, launchRodAngle))
return;
this.launchRodAngle = launchRodAngle;
@@ -157,7 +167,7 @@ public class SimulationOptions implements ChangeSource, Cloneable {
}
public void setLaunchRodDirection(double launchRodDirection) {
- launchRodDirection = MathUtil.reduce180(launchRodDirection);
+ launchRodDirection = MathUtil.reduce360(launchRodDirection);
if (MathUtil.equals(this.launchRodDirection, launchRodDirection))
return;
this.launchRodDirection = launchRodDirection;
diff --git a/core/src/net/sf/openrocket/simulation/SimulationStatus.java b/core/src/net/sf/openrocket/simulation/SimulationStatus.java
index 79b266a5a..17998a551 100644
--- a/core/src/net/sf/openrocket/simulation/SimulationStatus.java
+++ b/core/src/net/sf/openrocket/simulation/SimulationStatus.java
@@ -103,12 +103,12 @@ public class SimulationStatus implements Monitorable {
Quaternion o;
FlightConditions cond = new FlightConditions(this.configuration);
this.simulationConditions.getAerodynamicCalculator().getWorstCP(this.configuration, cond, null);
- double angle = -cond.getTheta() - this.simulationConditions.getLaunchRodDirection();
+ double angle = -cond.getTheta() - (Math.PI / 2.0 - this.simulationConditions.getLaunchRodDirection());
o = Quaternion.rotation(new Coordinate(0, 0, angle));
// Launch rod angle and direction
o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, this.simulationConditions.getLaunchRodAngle(), 0)));
- o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, 0, this.simulationConditions.getLaunchRodDirection())));
+ o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, 0, Math.PI / 2.0 - this.simulationConditions.getLaunchRodDirection())));
this.orientation = o;
this.rotationVelocity = Coordinate.NUL;
diff --git a/swing/src/net/sf/openrocket/gui/simulation/SimulationConditionsPanel.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationConditionsPanel.java
index f21746f4a..0ba49a3fc 100644
--- a/swing/src/net/sf/openrocket/gui/simulation/SimulationConditionsPanel.java
+++ b/swing/src/net/sf/openrocket/gui/simulation/SimulationConditionsPanel.java
@@ -352,7 +352,19 @@ public class SimulationConditionsPanel extends JPanel {
slider.setToolTipText(tip);
sub.add(slider, "w 75lp, wrap");
+ // Keep launch rod parallel to the wind.
+ BooleanModel intoWind = new BooleanModel(conditions, "LaunchIntoWind");
+ JCheckBox checkWind = new JCheckBox(intoWind);
+ //// Use International Standard Atmosphere
+ checkWind.setText(trans.get("simedtdlg.checkbox.Intowind"));
+ checkWind.setToolTipText(
+ trans.get("simedtdlg.checkbox.ttip.Intowind1") +
+ trans.get("simedtdlg.checkbox.ttip.Intowind2") +
+ trans.get("simedtdlg.checkbox.ttip.Intowind3") +
+ trans.get("simedtdlg.checkbox.ttip.Intowind4"));
+ sub.add(checkWind, "spanx, wrap unrel");
+
// Angle:
label = new JLabel(trans.get("simedtdlg.lbl.Angle"));
@@ -362,7 +374,7 @@ public class SimulationConditionsPanel extends JPanel {
sub.add(label);
m = new DoubleModel(conditions, "LaunchRodAngle", UnitGroup.UNITS_ANGLE,
- 0, SimulationOptions.MAX_LAUNCH_ROD_ANGLE);
+ -SimulationOptions.MAX_LAUNCH_ROD_ANGLE, SimulationOptions.MAX_LAUNCH_ROD_ANGLE);
spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
@@ -372,7 +384,7 @@ public class SimulationConditionsPanel extends JPanel {
unit = new UnitSelector(m);
unit.setToolTipText(tip);
sub.add(unit, "growx");
- slider = new BasicSlider(m.getSliderModel(0, Math.PI / 9,
+ slider = new BasicSlider(m.getSliderModel(-SimulationOptions.MAX_LAUNCH_ROD_ANGLE, 0,
SimulationOptions.MAX_LAUNCH_ROD_ANGLE));
slider.setToolTipText(tip);
sub.add(slider, "w 75lp, wrap");
@@ -381,19 +393,17 @@ public class SimulationConditionsPanel extends JPanel {
// Direction:
label = new JLabel(trans.get("simedtdlg.lbl.Direction"));
- //// Direction of the launch rod relative to the wind.
- //// = towards the wind,
- //// = downwind.
+ //// Direction of the launch rod.
tip = trans.get("simedtdlg.lbl.ttip.Direction1") +
UnitGroup.UNITS_ANGLE.toStringUnit(0) +
" " + trans.get("simedtdlg.lbl.ttip.Direction2") + " " +
- UnitGroup.UNITS_ANGLE.toStringUnit(Math.PI) +
+ UnitGroup.UNITS_ANGLE.toStringUnit(2*Math.PI) +
" " + trans.get("simedtdlg.lbl.ttip.Direction3");
label.setToolTipText(tip);
sub.add(label);
- m = new DoubleModel(conditions, "LaunchRodDirection", UnitGroup.UNITS_ANGLE,
- -Math.PI, Math.PI);
+ m = new DoubleModel(conditions, "LaunchRodDirection", 1.0, UnitGroup.UNITS_ANGLE,
+ 0, 2*Math.PI);
spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
@@ -403,10 +413,11 @@ public class SimulationConditionsPanel extends JPanel {
unit = new UnitSelector(m);
unit.setToolTipText(tip);
sub.add(unit, "growx");
- slider = new BasicSlider(m.getSliderModel(-Math.PI, Math.PI));
+ slider = new BasicSlider(m.getSliderModel(0, 2*Math.PI));
slider.setToolTipText(tip);
sub.add(slider, "w 75lp, wrap");
+
JButton restoreDefaults = new JButton(trans.get("simedtdlg.but.resettodefault"));
restoreDefaults.addActionListener(new ActionListener() {