SafetyMutex and rocket optimization updates
[debian/openrocket] / src / net / sf / openrocket / gui / plot / PlotConfiguration.java
index ebe5e96c00e3b88b8673b60eea155b646771847e..1cf5e97474ae5bad6fb2b452a17718c1aace5c86 100644 (file)
@@ -1,14 +1,14 @@
 package net.sf.openrocket.gui.plot;
 
-import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.List;
 import java.util.Set;
 
 import net.sf.openrocket.simulation.FlightDataBranch;
-import net.sf.openrocket.simulation.FlightEvent;
 import net.sf.openrocket.simulation.FlightDataType;
+import net.sf.openrocket.simulation.FlightEvent;
 import net.sf.openrocket.unit.Unit;
+import net.sf.openrocket.util.ArrayList;
 import net.sf.openrocket.util.BugException;
 import net.sf.openrocket.util.MathUtil;
 import net.sf.openrocket.util.Pair;
@@ -54,7 +54,7 @@ public class PlotConfiguration implements Cloneable {
                config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true);
                config.setEvent(FlightEvent.Type.GROUND_HIT, true);
                configs.add(config);
-
+               
                config = new PlotConfiguration("Stability vs. time");
                config.addPlotDataType(FlightDataType.TYPE_STABILITY, 0);
                config.addPlotDataType(FlightDataType.TYPE_CP_LOCATION, 1);
@@ -67,14 +67,14 @@ public class PlotConfiguration implements Cloneable {
                config.setEvent(FlightEvent.Type.GROUND_HIT, true);
                configs.add(config);
                
-               config = new PlotConfiguration("Drag coefficients vs. Mach number", 
+               config = new PlotConfiguration("Drag coefficients vs. Mach number",
                                FlightDataType.TYPE_MACH_NUMBER);
                config.addPlotDataType(FlightDataType.TYPE_DRAG_COEFF, 0);
                config.addPlotDataType(FlightDataType.TYPE_FRICTION_DRAG_COEFF, 0);
                config.addPlotDataType(FlightDataType.TYPE_BASE_DRAG_COEFF, 0);
                config.addPlotDataType(FlightDataType.TYPE_PRESSURE_DRAG_COEFF, 0);
                configs.add(config);
-
+               
                config = new PlotConfiguration("Roll characteristics");
                config.addPlotDataType(FlightDataType.TYPE_ROLL_RATE, 0);
                config.addPlotDataType(FlightDataType.TYPE_ROLL_MOMENT_COEFF, 1);
@@ -88,7 +88,7 @@ public class PlotConfiguration implements Cloneable {
                config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true);
                config.setEvent(FlightEvent.Type.GROUND_HIT, true);
                configs.add(config);
-
+               
                config = new PlotConfiguration("Angle of attack and orientation vs. time");
                config.addPlotDataType(FlightDataType.TYPE_AOA, 0);
                config.addPlotDataType(FlightDataType.TYPE_ORIENTATION_PHI);
@@ -100,7 +100,7 @@ public class PlotConfiguration implements Cloneable {
                config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true);
                config.setEvent(FlightEvent.Type.GROUND_HIT, true);
                configs.add(config);
-
+               
                config = new PlotConfiguration("Simulation time step and computation time");
                config.addPlotDataType(FlightDataType.TYPE_TIME_STEP);
                config.addPlotDataType(FlightDataType.TYPE_COMPUTATION_TIME);
@@ -111,15 +111,15 @@ public class PlotConfiguration implements Cloneable {
                config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true);
                config.setEvent(FlightEvent.Type.GROUND_HIT, true);
                configs.add(config);
-
+               
                DEFAULT_CONFIGURATIONS = configs.toArray(new PlotConfiguration[0]);
        }
        
-       
-       
+
+
        /** Bonus given for the first type being on the first axis */
        private static final double BONUS_FIRST_TYPE_ON_FIRST_AXIS = 1.0;
-
+       
        /**
         * Bonus given if the first axis includes zero (to prefer first axis having zero over 
         * the others) 
@@ -132,11 +132,11 @@ public class PlotConfiguration implements Cloneable {
        /** Bonus given for only using a single axis. */
        private static final double BONUS_ONLY_ONE_AXIS = 50.0;
        
-       
-       private static final double INCLUDE_ZERO_DISTANCE = 0.3;  // 30% of total range
-       
+
+       private static final double INCLUDE_ZERO_DISTANCE = 0.3; // 30% of total range
        
 
+
        /** The data types to be plotted. */
        private ArrayList<FlightDataType> plotDataTypes = new ArrayList<FlightDataType>();
        
@@ -144,24 +144,24 @@ public class PlotConfiguration implements Cloneable {
        
        /** The corresponding Axis on which they will be plotted, or null to auto-select. */
        private ArrayList<Integer> plotDataAxes = new ArrayList<Integer>();
-
+       
        private EnumSet<FlightEvent.Type> events = EnumSet.noneOf(FlightEvent.Type.class);
        
        /** The domain (x) axis. */
        private FlightDataType domainAxisType = null;
        private Unit domainAxisUnit = null;
        
-       
+
        /** All available axes. */
        private final int axesCount;
        private ArrayList<Axis> allAxes = new ArrayList<Axis>();
        
-       
-       
+
+
        private String name = null;
        
        
-       
+
        public PlotConfiguration() {
                this(null, FlightDataType.TYPE_TIME);
        }
@@ -181,9 +181,9 @@ public class PlotConfiguration implements Cloneable {
        }
        
        
-       
-       
-       
+
+
+
        public FlightDataType getDomainAxisType() {
                return domainAxisType;
        }
@@ -191,7 +191,7 @@ public class PlotConfiguration implements Cloneable {
        public void setDomainAxisType(FlightDataType type) {
                boolean setUnit;
                
-               if (domainAxisType != null  &&  domainAxisType.getUnitGroup() == type.getUnitGroup())
+               if (domainAxisType != null && domainAxisType.getUnitGroup() == type.getUnitGroup())
                        setUnit = false;
                else
                        setUnit = true;
@@ -207,19 +207,19 @@ public class PlotConfiguration implements Cloneable {
        
        public void setDomainAxisUnit(Unit u) {
                if (!domainAxisType.getUnitGroup().contains(u)) {
-                       throw new IllegalArgumentException("Setting unit "+u+" to type "+domainAxisType);
+                       throw new IllegalArgumentException("Setting unit " + u + " to type " + domainAxisType);
                }
                domainAxisUnit = u;
        }
        
        
-       
+
        public void addPlotDataType(FlightDataType type) {
                plotDataTypes.add(type);
                plotDataUnits.add(type.getUnitGroup().getDefaultUnit());
                plotDataAxes.add(-1);
        }
-
+       
        public void addPlotDataType(FlightDataType type, int axis) {
                if (axis >= axesCount) {
                        throw new IllegalArgumentException("Axis index too large");
@@ -228,10 +228,10 @@ public class PlotConfiguration implements Cloneable {
                plotDataUnits.add(type.getUnitGroup().getDefaultUnit());
                plotDataAxes.add(axis);
        }
-
-
        
        
+
+
        public void setPlotDataType(int index, FlightDataType type) {
                FlightDataType origType = plotDataTypes.get(index);
                plotDataTypes.set(index, type);
@@ -243,7 +243,7 @@ public class PlotConfiguration implements Cloneable {
        
        public void setPlotDataUnit(int index, Unit unit) {
                if (!plotDataTypes.get(index).getUnitGroup().contains(unit)) {
-                       throw new IllegalArgumentException("Attempting to set unit "+unit+" to group "
+                       throw new IllegalArgumentException("Attempting to set unit " + unit + " to group "
                                        + plotDataTypes.get(index).getUnitGroup());
                }
                plotDataUnits.set(index, unit);
@@ -273,13 +273,15 @@ public class PlotConfiguration implements Cloneable {
        }
        
        
-       
-       public FlightDataType getType (int index) {
+
+       public FlightDataType getType(int index) {
                return plotDataTypes.get(index);
        }
+       
        public Unit getUnit(int index) {
                return plotDataUnits.get(index);
        }
+       
        public int getAxis(int index) {
                return plotDataAxes.get(index);
        }
@@ -292,7 +294,7 @@ public class PlotConfiguration implements Cloneable {
        /// Events
        
        public Set<FlightEvent.Type> getActiveEvents() {
-               return (Set<FlightEvent.Type>) events.clone();
+               return events.clone();
        }
        
        public void setEvent(FlightEvent.Type type, boolean active) {
@@ -308,9 +310,9 @@ public class PlotConfiguration implements Cloneable {
        }
        
        
-       
-       
-       
+
+
+
        public List<Axis> getAllAxes() {
                List<Axis> list = new ArrayList<Axis>();
                list.addAll(allAxes);
@@ -335,7 +337,7 @@ public class PlotConfiguration implements Cloneable {
        }
        
        
-       
+
        /**
         * Find the best combination of the auto-selectable axes.
         * 
@@ -350,8 +352,8 @@ public class PlotConfiguration implements Cloneable {
        }
        
        
-       
-       
+
+
        /**
         * Recursively search for the best combination of the auto-selectable axes.
         * This is a brute-force search method.
@@ -364,23 +366,23 @@ public class PlotConfiguration implements Cloneable {
                // Create copy to fill in
                PlotConfiguration copy = this.clone();
                
-               int autoindex; 
-               for (autoindex=0; autoindex < plotDataAxes.size(); autoindex++) {
+               int autoindex;
+               for (autoindex = 0; autoindex < plotDataAxes.size(); autoindex++) {
                        if (plotDataAxes.get(autoindex) < 0)
                                break;
                }
                
-               
+
                if (autoindex >= plotDataAxes.size()) {
                        // All axes have been assigned, just return since we are already the best
                        return new Pair<PlotConfiguration, Double>(copy, copy.getGoodnessValue(data));
                }
                
-               
+
                // Set the auto-selected index one at a time and choose the best one
                PlotConfiguration best = null;
                double bestValue = Double.NEGATIVE_INFINITY;
-               for (int i=0; i < axesCount; i++) {
+               for (int i = 0; i < axesCount; i++) {
                        copy.plotDataAxes.set(autoindex, i);
                        Pair<PlotConfiguration, Double> result = copy.recursiveFillAutoAxes(data);
                        if (result.getV() > bestValue) {
@@ -393,9 +395,9 @@ public class PlotConfiguration implements Cloneable {
        }
        
        
-       
-       
-       
+
+
+
        /**
         * Fit the axes to hold the provided data.  All of the plotDataAxis elements must
         * be non-negative.
@@ -405,13 +407,13 @@ public class PlotConfiguration implements Cloneable {
        protected void fitAxes(FlightDataBranch data) {
                
                // Reset axes
-               for (Axis a: allAxes) {
+               for (Axis a : allAxes) {
                        a.reset();
                }
                
                // Add full range to the axes
                int length = plotDataTypes.size();
-               for (int i=0; i<length; i++) {
+               for (int i = 0; i < length; i++) {
                        FlightDataType type = plotDataTypes.get(i);
                        Unit unit = plotDataUnits.get(i);
                        int index = plotDataAxes.get(i);
@@ -422,16 +424,16 @@ public class PlotConfiguration implements Cloneable {
                        
                        double min = unit.toUnit(data.getMinimum(type));
                        double max = unit.toUnit(data.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) {
+               for (Axis a : allAxes) {
                        if (MathUtil.equals(a.getMinValue(), a.getMaxValue())) {
-                               a.addBound(a.getMinValue()-1);
-                               a.addBound(a.getMaxValue()+1);
+                               a.addBound(a.getMinValue() - 1);
+                               a.addBound(a.getMaxValue() + 1);
                        }
                        
                        double addition = a.getRangeLength() * 0.03;
@@ -444,8 +446,8 @@ public class PlotConfiguration implements Cloneable {
                                a.addBound(0);
                        }
                }
-
                
+
                // Check whether to use a common zero
                Axis left = allAxes.get(0);
                Axis right = allAxes.get(1);
@@ -455,11 +457,11 @@ public class PlotConfiguration implements Cloneable {
                                Double.isNaN(left.getMinValue()) || Double.isNaN(right.getMinValue()))
                        return;
                
-               
-               
+
+
                //// Compute common zero
                // TODO: MEDIUM: This algorithm may require tweaking
-
+               
                double min1 = left.getMinValue();
                double max1 = left.getMaxValue();
                double min2 = right.getMinValue();
@@ -469,14 +471,14 @@ public class PlotConfiguration implements Cloneable {
                double scale = Math.max(left.getRangeLength(), right.getRangeLength()) /
                                                Math.min(left.getRangeLength(), right.getRangeLength());
                
-               System.out.println("Scale: "+scale);
+               System.out.println("Scale: " + scale);
                
                scale = roundScale(scale);
                if (right.getRangeLength() > left.getRangeLength()) {
-                       scale = 1/scale;
+                       scale = 1 / scale;
                }
                System.out.println("Rounded scale: " + scale);
-
+               
                // Scale right axis, enlarge axes if necessary and scale back
                min2 *= scale;
                max2 *= scale;
@@ -487,53 +489,53 @@ public class PlotConfiguration implements Cloneable {
                min2 /= scale;
                max2 /= scale;
                
-               
-               
+
+
                // Scale to unit length
-//             double scale1 = left.getRangeLength();
-//             double scale2 = right.getRangeLength();
-//             
-//             double min1 = left.getMinValue() / scale1;
-//             double max1 = left.getMaxValue() / scale1;
-//             double min2 = right.getMinValue() / scale2;
-//             double max2 = right.getMaxValue() / scale2;
-//             
-//             // Combine unit ranges
-//             min1 = MathUtil.min(min1, min2);
-//             min2 = min1;
-//             max1 = MathUtil.max(max1, max2);
-//             max2 = max1;
-//             
-//             // Scale up
-//             min1 *= scale1;
-//             max1 *= scale1;
-//             min2 *= scale2;
-//             max2 *= scale2;
-//             
-//             // Compute common scale
-//             double range1 = max1-min1;
-//             double range2 = max2-min2;
-//             
-//             double scale = MathUtil.max(range1, range2) / MathUtil.min(range1, range2);
-//             double roundScale = roundScale(scale);
-//
-//             if (range2 < range1) {
-//                     if (roundScale < scale) {
-//                             min2 = min1 / roundScale;
-//                             max2 = max1 / roundScale;
-//                     } else {
-//                             min1 = min2 * roundScale;
-//                             max1 = max2 * roundScale;
-//                     }
-//             } else {
-//                     if (roundScale > scale) {
-//                             min2 = min1 * roundScale;
-//                             max2 = max1 * roundScale;
-//                     } else {
-//                             min1 = min2 / roundScale;
-//                             max1 = max2 / roundScale;
-//                     }
-//             }
+               //              double scale1 = left.getRangeLength();
+               //              double scale2 = right.getRangeLength();
+               //              
+               //              double min1 = left.getMinValue() / scale1;
+               //              double max1 = left.getMaxValue() / scale1;
+               //              double min2 = right.getMinValue() / scale2;
+               //              double max2 = right.getMaxValue() / scale2;
+               //              
+               //              // Combine unit ranges
+               //              min1 = MathUtil.min(min1, min2);
+               //              min2 = min1;
+               //              max1 = MathUtil.max(max1, max2);
+               //              max2 = max1;
+               //              
+               //              // Scale up
+               //              min1 *= scale1;
+               //              max1 *= scale1;
+               //              min2 *= scale2;
+               //              max2 *= scale2;
+               //              
+               //              // Compute common scale
+               //              double range1 = max1-min1;
+               //              double range2 = max2-min2;
+               //              
+               //              double scale = MathUtil.max(range1, range2) / MathUtil.min(range1, range2);
+               //              double roundScale = roundScale(scale);
+               //
+               //              if (range2 < range1) {
+               //                      if (roundScale < scale) {
+               //                              min2 = min1 / roundScale;
+               //                              max2 = max1 / roundScale;
+               //                      } else {
+               //                              min1 = min2 * roundScale;
+               //                              max1 = max2 * roundScale;
+               //                      }
+               //              } else {
+               //                      if (roundScale > scale) {
+               //                              min2 = min1 * roundScale;
+               //                              max2 = max1 * roundScale;
+               //                      } else {
+               //                              min1 = min2 / roundScale;
+               //                              max1 = max2 / roundScale;
+               //                      }
+               //              }
                
                // Apply scale
                left.addBound(min1);
@@ -569,11 +571,11 @@ public class PlotConfiguration implements Cloneable {
                } else {
                        scale = 1;
                }
-               return scale*mul;
+               return scale * mul;
        }
        
        
-       
+
        private double roundScaleUp(double scale) {
                double mul = 1;
                while (scale >= 10) {
@@ -596,10 +598,10 @@ public class PlotConfiguration implements Cloneable {
                } else {
                        scale = 1;
                }
-               return scale*mul;
+               return scale * mul;
        }
        
-
+       
        private double roundScaleDown(double scale) {
                double mul = 1;
                while (scale >= 10) {
@@ -620,11 +622,11 @@ public class PlotConfiguration implements Cloneable {
                } else {
                        scale = 1;
                }
-               return scale*mul;
+               return scale * mul;
        }
        
        
-       
+
        /**
         * Fits the axis ranges to the data and returns the "goodness value" of this 
         * selection of axes.  All plotDataAxis elements must be non-null.
@@ -661,12 +663,12 @@ public class PlotConfiguration implements Cloneable {
                        if (MathUtil.equals(min, max))
                                continue;
                        
-                       double d = (max-min) / axis.getRangeLength();
-                       d = Math.sqrt(d);  // Prioritize small ranges
+                       double d = (max - min) / axis.getRangeLength();
+                       d = Math.sqrt(d); // Prioritize small ranges
                        goodness += d * 100.0;
                }
                
-               
+
                /*
                 * Add extra points for specific things.
                 */
@@ -682,7 +684,7 @@ public class PlotConfiguration implements Cloneable {
                
                // A boost if a common zero was used in the ranging
                Axis right = allAxes.get(1);
-               if (left.getMinValue() <= 0 &&  left.getMaxValue() >= 0 &&
+               if (left.getMinValue() <= 0 && left.getMaxValue() >= 0 &&
                                right.getMinValue() <= 0 && right.getMaxValue() >= 0)
                        goodness += BONUS_COMMON_ZERO;
                
@@ -694,7 +696,7 @@ public class PlotConfiguration implements Cloneable {
        }
        
        
-       
+
        /**
         * Reset the units of this configuration to the default units. Returns this
         * PlotConfiguration.
@@ -702,16 +704,15 @@ public class PlotConfiguration implements Cloneable {
         * @return   this PlotConfiguration.
         */
        public PlotConfiguration resetUnits() {
-               for (int i=0; i < plotDataTypes.size(); i++) {
+               for (int i = 0; i < plotDataTypes.size(); i++) {
                        plotDataUnits.set(i, plotDataTypes.get(i).getUnitGroup().getDefaultUnit());
                }
                return this;
        }
        
        
-       
-       
-       @SuppressWarnings("unchecked")
+
+
        @Override
        public PlotConfiguration clone() {
                try {
@@ -719,20 +720,20 @@ public class PlotConfiguration implements Cloneable {
                        PlotConfiguration copy = (PlotConfiguration) super.clone();
                        
                        // Shallow-clone all immutable lists
-                       copy.plotDataTypes = (ArrayList<FlightDataType>) this.plotDataTypes.clone();
-                       copy.plotDataAxes = (ArrayList<Integer>) this.plotDataAxes.clone();
-                       copy.plotDataUnits = (ArrayList<Unit>) this.plotDataUnits.clone();
+                       copy.plotDataTypes = this.plotDataTypes.clone();
+                       copy.plotDataAxes = this.plotDataAxes.clone();
+                       copy.plotDataUnits = this.plotDataUnits.clone();
                        copy.events = this.events.clone();
                        
                        // Deep-clone all Axis since they are mutable
                        copy.allAxes = new ArrayList<Axis>();
-                       for (Axis a: this.allAxes) {
+                       for (Axis a : this.allAxes) {
                                copy.allAxes.add(a.clone());
                        }
                        
                        return copy;
                        
-                       
+
                } catch (CloneNotSupportedException e) {
                        throw new BugException("BUG! Could not clone().");
                }