Bug 13132 fixed: There were missing graduations when data_bound interval was too... 28/13328/2
Calixte DENIZET [Fri, 6 Dec 2013 11:45:39 +0000 (12:45 +0100)]
Change-Id: Ibf2be72949863697e879d8a0dc33215f53f836d2

scilab/CHANGES_5.5.X
scilab/modules/graphics/tests/nonreg_tests/bug_13132.tst [new file with mode: 0644]
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/ruler/graduations/AbstractGraduations.java
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/ruler/graduations/LinearGraduations.java
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/ruler/graduations/TinyIntervalFormat.java

index 2685889..1faba6d 100644 (file)
@@ -287,6 +287,8 @@ Scilab Bug Fixes
 
 * Bug #13121 fixed - ode "rk" option crashed Scilab when the user derivative function failed.
 
+* Bug #13132 fixed - There were missing graduations when data_bounds interval was too small.
+
 
 Xcos Bug Fixes
 ==============
diff --git a/scilab/modules/graphics/tests/nonreg_tests/bug_13132.tst b/scilab/modules/graphics/tests/nonreg_tests/bug_13132.tst
new file mode 100644 (file)
index 0000000..4719e35
--- /dev/null
@@ -0,0 +1,23 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Calixte DENIZET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- TEST WITH GRAPHIC -->
+
+// <-- INTERACTIVE TEST -->
+
+// <-- Non-regression test for bug 13132 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/13132
+//
+// <-- Short Description -->
+// There were missing graduations when data_bound interval was too small
+
+scf();
+plot([0, 1], [0.00099, 0.0010082]);
+
+// Check if all main ticks on y-axis have a label
index 11fb5f5..a34f7b5 100644 (file)
@@ -23,6 +23,8 @@ import java.text.DecimalFormatSymbols;
  */
 public abstract class AbstractGraduations implements Graduations {
 
+    protected static final double PRECISION = 1e-8;
+
     /** The left bracket used by {@link #toString()} */
     private static final String LEFT_BRACKET = "[";
 
@@ -145,10 +147,10 @@ public abstract class AbstractGraduations implements Graduations {
      * Equivalent to contain but for interval [0, upper-lower] (to avoid rounding error in computations)
      */
     public final boolean containRelative(double value) {
-        if (value == 0) {
+        if (value == 0 || Math.abs(value / (upperBound - lowerBound)) <= PRECISION) {
             return isLowerBoundIncluded;
         }
-        if (value == upperBound - lowerBound || Math.abs(1 - value / (upperBound - lowerBound)) <= 1e-15) {
+        if (value == upperBound - lowerBound || Math.abs(1 - value / (upperBound - lowerBound)) <= PRECISION) {
             return isUpperBoundIncluded;
         }
         return (0 < value) && (value < upperBound - lowerBound);
@@ -163,7 +165,7 @@ public abstract class AbstractGraduations implements Graduations {
             if (maxDisplayedValue < 1e-3) {
                 numberFormat = new DecimalFormat("0.##########E00");
             } else if (len <= 1e-3) {
-                numberFormat = new TinyIntervalFormat("0.####E00", "0.###E00");
+                numberFormat = new TinyIntervalFormat("0.####E00", "0.##E00");
             } else if (maxDisplayedValue >= 1e6) {
                 numberFormat = new DecimalFormat("0.##########E00");
             } else if (maxDisplayedValue < 1) {
@@ -207,7 +209,7 @@ public abstract class AbstractGraduations implements Graduations {
     }
 
     @Override
-    public final String toString() {
+    public String toString() {
         String lowerBoundBracket;
         String upperBoundBracket;
 
index 63bb745..418ee17 100644 (file)
@@ -97,27 +97,77 @@ public final class LinearGraduations extends AbstractGraduations implements Grad
         }
     }
 
+
+    private static final double mypow10(int e) {
+        double p = 10;
+        double r = 1;
+        final boolean signed = e < 0;
+        if (signed) {
+            e = -e;
+        }
+        while (e != 0) {
+            if ((e & 1) != 0) {
+                r *= p;
+            }
+            p *= p;
+            e >>= 1;
+        }
+
+        return signed ? 1 / r : r;
+    }
+
+    private static final long myceil(double x) {
+        if (x == 0) {
+            return 0L;
+        }
+
+        double r = Math.round(x);
+        if (Math.abs(1 - r / x) <= PRECISION) {
+            return (long) r;
+        }
+
+        return (long) Math.ceil(x);
+    }
+
     private Double getStepValue() {
         if (stepValue == null) {
-            stepValue = stepMantissa * Math.pow(10, stepExponent);
+            if (stepMantissa == 1) {
+                stepValue = mypow10(stepExponent);
+            } else {
+                stepValue = stepMantissa * mypow10(stepExponent);
+            }
         }
         return stepValue;
     }
 
-    private boolean isNewIndex(long index) {
+    private final long getIndex(double x) {
+        switch (stepMantissa) {
+            case 1:
+                return myceil(mypow10(-stepExponent) * x);
+            case 2:
+                return myceil(5 * mypow10(-stepExponent - 1) * x);
+            case 5:
+                return myceil(mypow10(-stepExponent - 1) * x * 2);
+            default:
+                return myceil(mypow10(-stepExponent) * x / stepMantissa);
+        }
+    }
+
+    private boolean isNewIndex(final long index) {
         /* We are now searching for value look like
          * index * (stepMantissa * 10^n) and we don't want (previousStrepMantissa * 10^k) value.
          */
 
-        if (stepMantissa == 1) {
-            // (5 * index * stepMantissa) % 10 != 0
-            return (index % 2 != 0);
-        } else if (stepMantissa == 2) {
-            // (2 * index * stepMantissa) % 10 != 0
-            return (index % 5 != 0);
-        } else {
-            // (5 * index * stepMantissa) % 10 != 0
-            return ((index * stepMantissa) % 2 != 0);
+        switch (stepMantissa) {
+            case 1:
+                // (5 * index * stepMantissa) % 10 != 0
+                return (index % 2) != 0;
+            case 2:
+                // (2 * index * stepMantissa) % 10 != 0
+                return (index % 5) != 0;
+            default:
+                // (5 * index * stepMantissa) % 10 != 0
+                return ((index * stepMantissa) % 2) != 0;
         }
     }
 
@@ -131,11 +181,11 @@ public final class LinearGraduations extends AbstractGraduations implements Grad
             newValues = new LinkedList<Double>();
             final double lb = getLowerBound();
 
-            long currentIndex = (long) Math.ceil(lb / getStepValue());
+            long currentIndex = getIndex(lb);
             double currentValue = getStepValue() * currentIndex;
             double value = currentValue - lb;
 
-            if (value == 0 && (!containRelative(value))) {
+            if (value == 0 && !containRelative(value)) {
                 value += getStepValue();
                 currentIndex++;
             }
@@ -157,7 +207,7 @@ public final class LinearGraduations extends AbstractGraduations implements Grad
         if (allValues == null) {
             final double lb = getLowerBound();
             allValues = new LinkedList<Double>();
-            double currentValue = getStepValue() * Math.ceil(lb / getStepValue());
+            double currentValue = getStepValue() * getIndex(lb);
             double value = currentValue - lb;
 
             if (value == 0 && !containRelative(value)) {
@@ -233,4 +283,12 @@ public final class LinearGraduations extends AbstractGraduations implements Grad
             return 2;
         }
     }
+
+    @Override
+    public String toString() {
+        String s = super.toString();
+        s += "; stepMantissa=" + stepMantissa + "; stepExponent=" + stepExponent + "; parent=" + getParentGraduations();
+
+        return s;
+    }
 }
index edbf431..efe7dd6 100644 (file)
@@ -42,6 +42,7 @@ public class TinyIntervalFormat extends DecimalFormat {
      */
     public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) {
         double[] parts = getParts(number);
+
         if (parts[1] == 0) {
             return super.format(number, result, fieldPosition);
         }
@@ -58,9 +59,11 @@ public class TinyIntervalFormat extends DecimalFormat {
             } else if (parts[1] < 0) {
                 result.append("-");
             }
+
+            return fracFormat.format(Math.abs(parts[1]), result, fieldPosition);
         }
 
-        return fracFormat.format(Math.abs(parts[1]), result, fieldPosition);
+        return fracFormat.format(parts[1], result, fieldPosition);
     }
 
     /**
@@ -81,12 +84,12 @@ public class TinyIntervalFormat extends DecimalFormat {
         double p = 1;
         double y = x;
         double f = y - Math.round(y);
-        while (Math.abs(f) > 1e-3) {
+        while (Math.abs(f) > 1e-2) {
             y *= 10;
             p *= 10;
             f = y - Math.round(y);
         }
 
-        return new double[] {Math.round(y) / p, f};
+        return new double[] {Math.round(y) / p, f / p};
     }
 }