Component preset updates
[debian/openrocket] / core / src / net / sf / openrocket / unit / FractionalUnit.java
index 26436478097049bd7f8f9928fce2408bac41fc90..740e4776d0b5ba73489c10335337bc204088b85a 100644 (file)
@@ -4,63 +4,93 @@ import java.text.DecimalFormat;
 import java.text.NumberFormat;
 import java.util.ArrayList;
 
-public class FractionalUnit extends Unit {
+import net.sf.openrocket.util.Chars;
 
+public class FractionalUnit extends Unit {
+       
+       private final static char FRACTION = Chars.FRACTION;
+       
+       private final static String[] NUMERATOR = {
+                       "\u2070", // 0
+                       "\u00B9", // 1
+                       "\u00B2", // 2
+                       "\u00B3", // 3
+                       "\u2074", // 4
+                       "\u2075", // 5
+                       "\u2076", // 6
+                       "\u2077", // 7
+                       "\u2078", // 8
+                       "\u2079" // 9
+       };
+       
+       private final static String[] DENOMINATOR = {
+                       "\u2080", // 0
+                       "\u2081", // 1
+                       "\u2082", // 2
+                       "\u2083", // 3
+                       "\u2084", // 4
+                       "\u2085", // 5
+                       "\u2086", // 6
+                       "\u2087", // 7
+                       "\u2088", // 8
+                       "\u2089" // 9
+       };
+       
        // This is the base of the fractions.  ie, 16d for 1/16ths.
        private final int fractionBase;
        // This is 1d/fractionBase;
        private final double fractionValue;
-
+       
        // This is the value used when incrementing/decrementing.
        private final double incrementValue;
-
+       
        // If the actual value differs from the decimal representation by more than this,
        // we display as decimals.
        private final double epsilon;
-
+       
        private final String unitLabel;
-
+       
        public FractionalUnit(double multiplier, String unit, String unitLabel, int fractionBase, double incrementValue) {
-               this( multiplier, unit, unitLabel, fractionBase, incrementValue, 0.1d/fractionBase);
+               this(multiplier, unit, unitLabel, fractionBase, incrementValue, 0.1d / fractionBase);
        }
-
+       
        public FractionalUnit(double multiplier, String unit, String unitLabel, int fractionBase, double incrementValue, double epsilon) {
                super(multiplier, unit);
                this.unitLabel = unitLabel;
                this.fractionBase = fractionBase;
-               this.fractionValue = 1.0d/fractionBase;
+               this.fractionValue = 1.0d / fractionBase;
                this.incrementValue = incrementValue;
                this.epsilon = epsilon;
        }
-
+       
        @Override
        public double round(double value) {
-               return roundTo( value, fractionValue );
+               return roundTo(value, fractionValue);
        }
-
-       private double roundTo( double value, double fraction ) {
-               double remainder = Math.IEEEremainder( value, fraction );
+       
+       private double roundTo(double value, double fraction) {
+               double remainder = Math.IEEEremainder(value, fraction);
                return value - remainder;
        }
-
+       
        @Override
        public double getNextValue(double value) {
                double rounded = roundTo(value, incrementValue);
-               if ( rounded <= value + epsilon) {
+               if (rounded <= value + epsilon) {
                        rounded += incrementValue;
                }
                return rounded;
        }
-
+       
        @Override
        public double getPreviousValue(double value) {
                double rounded = roundTo(value, incrementValue);
-               if ( rounded >= value - epsilon ) {
+               if (rounded >= value - epsilon) {
                        rounded -= incrementValue;
                }
                return rounded;
        }
-
+       
        @Override
        public Tick[] getTicks(double start, double end, double minor, double major) {
                // Convert values
@@ -68,121 +98,148 @@ public class FractionalUnit extends Unit {
                end = toUnit(end);
                minor = toUnit(minor);
                major = toUnit(major);
-
+               
                if (minor <= 0 || major <= 0 || major < minor) {
-                       throw new IllegalArgumentException("getTicks called with minor="+minor+" major="+major);
+                       throw new IllegalArgumentException("getTicks called with minor=" + minor + " major=" + major);
                }
-
+               
                ArrayList<Tick> ticks = new ArrayList<Tick>();
-
-               int mod2,mod3,mod4;  // Moduli for minor-notable, major-nonnotable, major-notable
+               
+               int mod2, mod3, mod4; // Moduli for minor-notable, major-nonnotable, major-notable
                double minstep;
-
+               
                // Find the smallest possible step size
-               double one=1;
+               double one = 1;
                while (one > minor)
                        one /= 2;
                while (one < minor)
                        one *= 2;
                minstep = one;
                mod2 = 16;
-
+               
                // Find step size for major ticks
                one = 1;
                while (one > major)
                        one /= 10;
                while (one < major)
                        one *= 10;
-               if (one/2 >= major) {
+               if (one / 2 >= major) {
                        // major step is round-five, major-notable is next round-ten
-                       double majorstep = one/2;
-                       mod3 = (int)Math.round(majorstep/minstep);
-                       mod4 = mod3*2;
+                       double majorstep = one / 2;
+                       mod3 = (int) Math.round(majorstep / minstep);
+                       mod4 = mod3 * 2;
                } else {
                        // major step is round-ten, major-notable is next round-ten
-                       mod3 = (int)Math.round(one/minstep);
-                       mod4 = mod3*10;
+                       mod3 = (int) Math.round(one / minstep);
+                       mod4 = mod3 * 10;
                }
                // Check for clashes between minor-notable and major-nonnotable
                if (mod3 == mod2) {
-                       if (mod2==2)
-                               mod2 = 1;  // Every minor tick is notable
+                       if (mod2 == 2)
+                               mod2 = 1; // Every minor tick is notable
                        else
-                               mod2 = 5;  // Every fifth minor tick is notable
+                               mod2 = 5; // Every fifth minor tick is notable
                }
-
-
+               
+               
                // Calculate starting position
-               int pos = (int)Math.ceil(start/minstep);
+               int pos = (int) Math.ceil(start / minstep);
                //              System.out.println("mod2="+mod2+" mod3="+mod3+" mod4="+mod4);
-               while (pos*minstep <= end) {
-                       double unitValue = pos*minstep;
+               while (pos * minstep <= end) {
+                       double unitValue = pos * minstep;
                        double value = fromUnit(unitValue);
-
-                       if (pos%mod4 == 0)
-                               ticks.add(new Tick(value,unitValue,true,true));
-                       else if (pos%mod3 == 0)
-                               ticks.add(new Tick(value,unitValue,true,false));
-                       else if (pos%mod2 == 0)
-                               ticks.add(new Tick(value,unitValue,false,true));
+                       
+                       if (pos % mod4 == 0)
+                               ticks.add(new Tick(value, unitValue, true, true));
+                       else if (pos % mod3 == 0)
+                               ticks.add(new Tick(value, unitValue, true, false));
+                       else if (pos % mod2 == 0)
+                               ticks.add(new Tick(value, unitValue, false, true));
                        else
-                               ticks.add(new Tick(value,unitValue,false,false));
-
+                               ticks.add(new Tick(value, unitValue, false, false));
+                       
                        pos++;
                }
-
+               
                return ticks.toArray(new Tick[0]);
        }
-
-
+       
+       
        @Override
        public String toString(double value) {
-
+               
                double correctVal = toUnit(value);
                double val = round(correctVal);
-
-
-               if ( Math.abs( val - correctVal ) > epsilon ) {
+               
+               
+               if (Math.abs(val - correctVal) > epsilon) {
                        NumberFormat decFormat = new DecimalFormat("#.###");
                        return decFormat.format(correctVal);
                }
-
+               
                NumberFormat intFormat = new DecimalFormat("#");
                double sign = Math.signum(val);
-
+               
                double posValue = sign * val;
-
+               
                double intPart = Math.floor(posValue);
-
-               double frac = Math.rint((posValue - intPart)/fractionValue);
+               
+               double frac = Math.rint((posValue - intPart) / fractionValue);
                double fracBase = fractionBase;
-
+               
                // Reduce fraction.
-               while ( frac > 0 && fracBase > 2 && frac % 2 == 0 ) {
+               while (frac > 0 && fracBase > 2 && frac % 2 == 0) {
                        frac /= 2.0;
                        fracBase /= 2.0;
                }
-
+               
                posValue *= sign;
-
-               if ( frac == 0.0 )  {
+               
+               if (frac == 0.0) {
                        return intFormat.format(posValue);
-               } else if (intPart == 0.0 ){
-                       return intFormat.format(sign*frac) + "/" + intFormat.format(fracBase);
+               } else if (intPart == 0.0) {
+                       return (sign < 0 ? "-" : "") + numeratorString(Double.valueOf(frac).intValue())
+                                       + FRACTION + denominatorString(Double.valueOf(fracBase).intValue());
                } else {
-                       return intFormat.format(sign*intPart) + " " + intFormat.format(frac) + "/" + intFormat.format(fracBase);
+                       return intFormat.format(sign * intPart) + " " + numeratorString(Double.valueOf(frac).intValue())
+                                       + FRACTION + denominatorString(Double.valueOf(fracBase).intValue());
                }
-
+               
        }
-
+       
+       private String numeratorString(int value) {
+               
+               String rep = "";
+               if (value == 0) {
+                       return "0";
+               }
+               while (value > 0) {
+                       rep = NUMERATOR[value % 10] + rep;
+                       value = value / 10;
+               }
+               return rep;
+       }
+       
+       private String denominatorString(int value) {
+               String rep = "";
+               if (value == 0) {
+                       return "0";
+               }
+               while (value > 0) {
+                       rep = DENOMINATOR[value % 10] + rep;
+                       value = value / 10;
+               }
+               return rep;
+       }
+       
        @Override
        public String toStringUnit(double value) {
                if (Double.isNaN(value))
                        return "N/A";
-
+               
                String s = toString(value);
                s += " " + unitLabel;
                return s;
        }
-
+       
 }