]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/GridUtils.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / utils / GridUtils.java
diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/GridUtils.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/GridUtils.java
new file mode 100644 (file)
index 0000000..c466fb2
--- /dev/null
@@ -0,0 +1,295 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.scenegraph.utils;\r
+\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Point2D;\r
+import java.util.Arrays;\r
+\r
+/**\r
+ * A set of utilities for calculating even spacings. Useful for grid/rules\r
+ * spacing calculations.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ * @author Marko Luukkainen (original)\r
+ */\r
+public final class GridUtils {\r
+\r
+    private static double gridLineEvenSpacings[] = new double[] { 1.0, 2.0, 5.0, 10.0 };\r
+\r
+    /**\r
+     * Returns next even grid spacing for value.\r
+     * \r
+     * @param value to round to nearest even grid spacing\r
+     * @param gridSize the base grid size that will multiply the even spacings\r
+     *        returned by this method\r
+     * @param lessThan <code>true</code> to select the nearest even spacing <=\r
+     *        value or <code>false</code> to select the nearest even spacing >=\r
+     *        value\r
+     * @return the calculated nearest even grid spacing\r
+     */\r
+    public static double getEvenGridSpacing(double value, double gridSize, boolean lessThan) {\r
+        double exp = Math.floor(Math.log10(value));\r
+        double gs = Math.pow(10.0, exp) * gridSize;\r
+//        System.out.println("getEvenGridSpacing(" + value + ", " + gridSize + ", " + lessThan + "): " + exp + ", " + gs);\r
+        int i = lessThan ? 1 : 0;\r
+        int max = lessThan ? gridLineEvenSpacings.length : gridLineEvenSpacings.length - 1;\r
+        while (i < max) {\r
+//            System.out.println("COMPARE(" + gridLineEvenSpacings[i] + "): " + gridLineEvenSpacings[i]*gs + " >= " + value);\r
+            if (gridLineEvenSpacings[i] * gs >= value) {\r
+                if (lessThan)\r
+                    --i;\r
+                break;\r
+            }\r
+            i++;\r
+        }\r
+        // FIXME: this is a workaround to keep the next line from causing an NPE\r
+        // Need to check the calculations and make some sense into this code once\r
+        // again to be sure.\r
+        if (i >= gridLineEvenSpacings.length)\r
+            return 2 * gridLineEvenSpacings[gridLineEvenSpacings.length - 1] * gs;\r
+        return gridLineEvenSpacings[i] * gs;\r
+    }\r
+\r
+    /**\r
+     * Returns next even grid spacing for value with the assumed grid size of\r
+     * <code>1.0</code>.\r
+     * \r
+     * @param value to round to nearest even grid spacing\r
+     * @param lessThan <code>true</code> to select the nearest even spacing <=\r
+     *        value or <code>false</code> to select the nearest even spacing >=\r
+     *        value\r
+     * @return the calculated nearest even grid spacing\r
+     */\r
+    public static double getEvenGridSpacing(double value, boolean lessThan) {\r
+        return getEvenGridSpacing(value, 1.0, lessThan);\r
+    }\r
+\r
+    /**\r
+     * Returns next even number for value and exponent of the value.\r
+     * \r
+     * @param value in units\r
+     * @param array of at least two elements where the results will be put\r
+     * @return the specified array, where even number is element [0] and\r
+     *         exponent is element [1]\r
+     */\r
+    public static double[] getEvenGridSpacingWithExp(double value, double[] array) {\r
+        if (array == null)\r
+            throw new NullPointerException("null array");\r
+        if (array.length < 2)\r
+            throw new NullPointerException("");\r
+        \r
+        /* TODO Time-Spacing        \r
+        1s 5s 10s 20s 30s        \r
+        1m 5m 10m 20m 30m   \r
+        1h 2h 6h 12h         \r
+         */\r
+\r
+        double sig = Math.signum( value );\r
+        double exp = Math.floor(Math.log10( Math.abs(value) ));\r
+        double gs = Math.pow(10.0, exp);\r
+        int i = 0;\r
+        while (i < gridLineEvenSpacings.length - 1) {\r
+            if (gridLineEvenSpacings[i] * gs >= value) {\r
+                break;\r
+            }\r
+            i++;\r
+        }\r
+        array[0] = gridLineEvenSpacings[i] * gs * sig;\r
+        array[1] = exp;\r
+        return array;\r
+    }\r
+\r
+    /**\r
+     * Returns next even number for value and exponent of the value.\r
+     * \r
+     * @param value in units\r
+     * @return array where even number is [0] element and exponent is [1]\r
+     *         element\r
+     */\r
+    public static double[] getEvenGridSpacingWithExp(double value) {\r
+        return getEvenGridSpacingWithExp(value, new double[2]);\r
+    }\r
+\r
+    /**\r
+     * @param fromCoord\r
+     * @param gridSpacing\r
+     * @return\r
+     */\r
+    public static double distanceToNextGridCoord(double fromCoord, double gridSpacing) {\r
+        double mod = Math.IEEEremainder(fromCoord, gridSpacing);\r
+        if (mod < 0) {\r
+            return -mod;\r
+        } else if (mod > 0) {\r
+            return (gridSpacing - mod);\r
+        }\r
+        return 0;\r
+    }\r
+\r
+    /**\r
+     * @param fromCoord\r
+     * @param gridSpacing\r
+     * @return\r
+     */\r
+    public static double distanceToPrevGridCoord(double fromCoord, double gridSpacing) {\r
+        double mod = Math.IEEEremainder(fromCoord, gridSpacing);\r
+        if (mod < 0) {\r
+            return (gridSpacing + mod);\r
+        } else if (mod > 0) {\r
+            return mod;\r
+        }\r
+        return 0;\r
+    }\r
+    \r
+    /**\r
+     * @param coord\r
+     * @param gridSpacing\r
+     * @param scale\r
+     * @return\r
+     */\r
+    public static double distanceToNextGridCoordScaled(double coord, double gridSpacing, double scale) {\r
+        double result = distanceToNextGridCoord(coord, gridSpacing);\r
+        return result * scale;\r
+    }\r
+\r
+    /**\r
+     * @param coord\r
+     * @param gridSpacing\r
+     * @param scale\r
+     * @return\r
+     */\r
+    public static double distanceToPrevGridCoordScaled(double coord, double gridSpacing, double scale) {\r
+        double result = distanceToPrevGridCoord(coord, gridSpacing);\r
+        return result * scale;\r
+    }\r
+    \r
+    /**\r
+     * @param coord\r
+     * @param gridSpacing\r
+     * @return\r
+     */\r
+    public static double distanceToNearestGridCoord(double coord, double gridSpacing) {\r
+        double dist = GridUtils.distanceToNextGridCoord(coord, gridSpacing);\r
+        if (dist > gridSpacing / 2)\r
+            dist = dist - gridSpacing;\r
+        return dist;\r
+    }\r
+\r
+    /**\r
+     * @param tr\r
+     * @param gridSpacing\r
+     */\r
+    public static void snapToGrid(AffineTransform tr, double gridSpacing) {\r
+        double gdx = GridUtils.distanceToNearestGridCoord(tr.getTranslateX(), gridSpacing);\r
+        double gdy = GridUtils.distanceToNearestGridCoord(tr.getTranslateY(), gridSpacing);\r
+        //System.out.println("SNAP TO GRID: delta=(" + gdx + ", " + gdy + "), tr = " + tr);\r
+        tr.translate(gdx, gdy);\r
+    }\r
+\r
+    /**\r
+     * @param p\r
+     * @param gridSpacing\r
+     */\r
+    public static void snapToGrid(Point2D p, double gridSpacing) {\r
+        snapToGrid(p, gridSpacing, gridSpacing);\r
+    }\r
+\r
+    /**\r
+     * @param p\r
+     * @param gridXSpacing\r
+     * @param gridYSpacing\r
+     */\r
+    public static void snapToGrid(Point2D p, double gridXSpacing, double gridYSpacing) {\r
+        double x = p.getX();\r
+        double y = p.getY();\r
+        double gdx = GridUtils.distanceToNearestGridCoord(x, gridXSpacing);\r
+        double gdy = GridUtils.distanceToNearestGridCoord(y, gridYSpacing);\r
+        p.setLocation(x + gdx, y + gdy);\r
+    }\r
+\r
+    /**\r
+     * @param t\r
+     * @param gridSpacing\r
+     * @return\r
+     */\r
+    public static double snapToGrid(double t, double gridSpacing) {\r
+        double dt = GridUtils.distanceToNearestGridCoord(t, gridSpacing);\r
+        return t + dt;\r
+    }\r
+\r
+    /**\r
+     * Returns an even grid spacing where initialValue*scale <= limit.\r
+     * \r
+     * @param initialValue\r
+     * @param scale\r
+     * @param limit\r
+     * @param gridSize\r
+     * @param lessThan <code>true</code> to select the nearest even spacing <=\r
+     *        limit/scale or <code>false</code> to select the nearest even spacing >=\r
+     *        limit/scale\r
+     * @return\r
+     */\r
+    public static double limitedEvenGridSpacing(double initialValue, double scale, double limit, double gridSize, boolean lessThan) {\r
+        while (initialValue * scale > limit)\r
+            initialValue /= 2;\r
+        return getEvenGridSpacing(initialValue, gridSize, lessThan);\r
+    }\r
+\r
+    /**\r
+     * Returns an even grid spacing where initialValue*scale <= limit\r
+     * \r
+     * @param initialValue\r
+     * @param scale\r
+     * @param limit\r
+     * @param lessThan <code>true</code> to select the nearest even spacing <=\r
+     *        limit/scale or <code>false</code> to select the nearest even spacing >=\r
+     *        limit/scale\r
+     * @return\r
+     */\r
+    public static double limitedEvenGridSpacing(double initialValue, double scale, double limit, boolean lessThan) {\r
+        return limitedEvenGridSpacing(initialValue, scale, limit, 1.0, lessThan);\r
+    }\r
+\r
+    /**\r
+     * A simple test for these routines.\r
+     */\r
+    public static void main(String[] args) {\r
+        System.out.println(Arrays.toString(getEvenGridSpacingWithExp(15)));\r
+        System.out.println(Arrays.toString(getEvenGridSpacingWithExp(16.3)));\r
+        System.out.println(Arrays.toString(getEvenGridSpacingWithExp(143.41)));\r
+        System.out.println(Arrays.toString(getEvenGridSpacingWithExp(500.0)));\r
+        System.out.println(Arrays.toString(getEvenGridSpacingWithExp(10000.0)));\r
+        System.out.println(Arrays.toString(getEvenGridSpacingWithExp(0.5)));\r
+\r
+        //double aa[] = new double[2];\r
+        System.out.println(getEvenGridSpacing(15, true));\r
+        System.out.println(getEvenGridSpacing(15, false));\r
+        System.out.println(getEvenGridSpacing(16.3, true));\r
+        System.out.println(getEvenGridSpacing(16.3, false));\r
+        System.out.println(getEvenGridSpacing(143.41, true));\r
+        System.out.println(getEvenGridSpacing(143.41, false));\r
+        System.out.println(getEvenGridSpacing(500.0, true));\r
+        System.out.println(getEvenGridSpacing(500.0, false));\r
+        System.out.println(getEvenGridSpacing(10000.0, true));\r
+        System.out.println(getEvenGridSpacing(10000.0, false));\r
+        System.out.println(getEvenGridSpacing(0.5, true));\r
+        System.out.println(getEvenGridSpacing(0.5, false));\r
+        System.out.println(getEvenGridSpacing(0.045, true));\r
+        System.out.println(getEvenGridSpacing(0.045, false));\r
+        System.out.println(getEvenGridSpacing(0.000605, true));\r
+        System.out.println(getEvenGridSpacing(0.000605, false));\r
+\r
+        System.out.println(getEvenGridSpacing(143, 2.54, true));\r
+        System.out.println(getEvenGridSpacing(143, 2.54, false));\r
+    }\r
+\r
+}
\ No newline at end of file