diff --git a/core/src/net/sf/openrocket/simulation/FlightData.java b/core/src/net/sf/openrocket/simulation/FlightData.java index cd8ca8633..27f6c1318 100644 --- a/core/src/net/sf/openrocket/simulation/FlightData.java +++ b/core/src/net/sf/openrocket/simulation/FlightData.java @@ -137,6 +137,10 @@ public class FlightData { public FlightDataBranch getBranch(int n) { return branches.get(n); } + + public List getBranches() { + return branches; + } diff --git a/swing/src/net/sf/openrocket/gui/plot/PlotConfiguration.java b/swing/src/net/sf/openrocket/gui/plot/PlotConfiguration.java index e700c9080..70b2cfa9c 100644 --- a/swing/src/net/sf/openrocket/gui/plot/PlotConfiguration.java +++ b/swing/src/net/sf/openrocket/gui/plot/PlotConfiguration.java @@ -1,5 +1,6 @@ package net.sf.openrocket.gui.plot; +import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Set; @@ -37,7 +38,7 @@ public class PlotConfiguration implements Cloneable { config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.TUMBLE, true); - config.setEvent(FlightEvent.Type.EXCEPTION, true); + config.setEvent(FlightEvent.Type.EXCEPTION, true); configs.add(config); //// Total motion vs. time @@ -52,7 +53,7 @@ public class PlotConfiguration implements Cloneable { config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.TUMBLE, true); - config.setEvent(FlightEvent.Type.EXCEPTION, true); + config.setEvent(FlightEvent.Type.EXCEPTION, true); configs.add(config); //// Flight side profile @@ -65,7 +66,7 @@ public class PlotConfiguration implements Cloneable { config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.TUMBLE, true); - config.setEvent(FlightEvent.Type.EXCEPTION, true); + config.setEvent(FlightEvent.Type.EXCEPTION, true); configs.add(config); @@ -92,7 +93,7 @@ public class PlotConfiguration implements Cloneable { config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.TUMBLE, true); - config.setEvent(FlightEvent.Type.EXCEPTION, true); + config.setEvent(FlightEvent.Type.EXCEPTION, true); configs.add(config); //// Drag coefficients vs. Mach number @@ -102,7 +103,7 @@ public class PlotConfiguration implements Cloneable { config.addPlotDataType(FlightDataType.TYPE_FRICTION_DRAG_COEFF, 0); config.addPlotDataType(FlightDataType.TYPE_BASE_DRAG_COEFF, 0); config.addPlotDataType(FlightDataType.TYPE_PRESSURE_DRAG_COEFF, 0); - config.setEvent(FlightEvent.Type.EXCEPTION, true); + config.setEvent(FlightEvent.Type.EXCEPTION, true); configs.add(config); //// Roll characteristics @@ -119,7 +120,7 @@ public class PlotConfiguration implements Cloneable { config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.TUMBLE, true); - config.setEvent(FlightEvent.Type.EXCEPTION, true); + config.setEvent(FlightEvent.Type.EXCEPTION, true); configs.add(config); //// Angle of attack and orientation vs. time @@ -134,7 +135,7 @@ public class PlotConfiguration implements Cloneable { config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.TUMBLE, true); - config.setEvent(FlightEvent.Type.EXCEPTION, true); + config.setEvent(FlightEvent.Type.EXCEPTION, true); configs.add(config); //// Simulation time step and computation time @@ -148,7 +149,7 @@ public class PlotConfiguration implements Cloneable { config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.TUMBLE, true); - config.setEvent(FlightEvent.Type.EXCEPTION, true); + config.setEvent(FlightEvent.Type.EXCEPTION, true); configs.add(config); DEFAULT_CONFIGURATIONS = configs.toArray(new PlotConfiguration[0]); @@ -424,19 +425,19 @@ public class PlotConfiguration implements Cloneable { return new Pair(best, bestValue); } - - - - - + + + protected void fitAxes(FlightDataBranch data) { + this.fitAxes(Collections.singletonList(data)); + } + /** * Fit the axes to hold the provided data. All of the plotDataAxis elements must * be non-negative. *

* NOTE: This method assumes that only two axes are used. */ - protected void fitAxes(FlightDataBranch data) { - + public void fitAxes(List data) { // Reset axes for (Axis a : allAxes) { a.reset(); @@ -453,13 +454,18 @@ public class PlotConfiguration implements Cloneable { } Axis axis = allAxes.get(index); - double min = unit.toUnit(data.getMinimum(type)); - double max = unit.toUnit(data.getMaximum(type)); + double min = unit.toUnit(data.get(0).getMinimum(type)); + double max = unit.toUnit(data.get(0).getMaximum(type)); + + for (int j = 1; j < data.size(); j++) { + min = Math.min(min, unit.toUnit(data.get(j).getMinimum(type))); + max = Math.max(max, unit.toUnit(data.get(j).getMaximum(type))); + } axis.addBound(min); axis.addBound(max); } - + // Ensure non-zero (or NaN) range, add a few percent range, include zero if it is close for (Axis a : allAxes) { if (MathUtil.equals(a.getMinValue(), a.getMaxValue())) { @@ -491,41 +497,28 @@ public class PlotConfiguration implements Cloneable { //// Compute common zero - // TODO: MEDIUM: This algorithm may require tweaking double min1 = left.getMinValue(); double max1 = left.getMaxValue(); double min2 = right.getMinValue(); double max2 = right.getMaxValue(); - - // Calculate and round scaling factor - double scale = Math.max(left.getRangeLength(), right.getRangeLength()) / - Math.min(left.getRangeLength(), right.getRangeLength()); - - //System.out.println("Scale: " + scale); - - scale = roundScale(scale); - if (right.getRangeLength() > left.getRangeLength()) { - scale = 1 / scale; + + // Get the zero locations, scaled down to a value from 0 to 1 (0 = bottom of y axis, 1 = top) + double zeroLoc1 = -min1 / left.getRangeLength(); + double zeroLoc2 = -min2 / right.getRangeLength(); + + // Scale the right axis + if (zeroLoc1 > zeroLoc2) { + min2 = -max2 * (zeroLoc1 / (1 - zeroLoc1)); + } else { + max2 = min2 * (-1 / zeroLoc1 + 1); } - //System.out.println("Rounded scale: " + scale); - - // Scale right axis, enlarge axes if necessary and scale back - min2 *= scale; - max2 *= scale; - min1 = Math.min(min1, min2); - min2 = min1; - max1 = Math.max(max1, max2); - max2 = max1; - min2 /= scale; - max2 /= scale; - + // Apply scale left.addBound(min1); left.addBound(max1); right.addBound(min2); right.addBound(max2); - } diff --git a/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java b/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java index 3f85c04ff..9bcb0253f 100644 --- a/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java +++ b/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java @@ -134,7 +134,11 @@ public class SimulationPlot { // Fill the auto-selections based on first branch selected. FlightDataBranch mainBranch = simulation.getSimulatedData().getBranch(0); this.filled = config.fillAutoAxes(mainBranch); - List axes = filled.getAllAxes(); + + // Compute the axes based on the min and max value of all branches + PlotConfiguration plotConfig = filled.clone(); + plotConfig.fitAxes(simulation.getSimulatedData().getBranches()); + List minMaxAxes = plotConfig.getAllAxes(); // Create the data series for both axes XYSeriesCollection[] data = new XYSeriesCollection[2]; @@ -250,15 +254,8 @@ public class SimulationPlot { // Check whether axis has any data if (data[axisno].getSeriesCount() > 0) { // Create and set axis - double min = axes.get(axisno).getMinValue(); - double max = axes.get(axisno).getMaxValue(); - - for (Object series : data[axisno].getSeries()) { - if (series instanceof XYSeries) { - min = Math.min(min, ((XYSeries) series).getMinY()); - max = Math.max(max, ((XYSeries) series).getMaxY()); - } - } + double min = minMaxAxes.get(axisno).getMinValue(); + double max = minMaxAxes.get(axisno).getMaxValue(); NumberAxis axis = new PresetNumberAxis(min, max); axis.setLabel(axisLabel[axisno]);