1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.scenegraph.utils;
\r
14 import java.awt.geom.AffineTransform;
\r
15 import java.awt.geom.Point2D;
\r
16 import java.util.Arrays;
\r
19 * A set of utilities for calculating even spacings. Useful for grid/rules
\r
20 * spacing calculations.
\r
22 * @author Tuukka Lehtonen
\r
23 * @author Marko Luukkainen (original)
\r
25 public final class GridUtils {
\r
27 private static double gridLineEvenSpacings[] = new double[] { 1.0, 2.0, 5.0, 10.0 };
\r
30 * Returns next even grid spacing for value.
\r
32 * @param value to round to nearest even grid spacing
\r
33 * @param gridSize the base grid size that will multiply the even spacings
\r
34 * returned by this method
\r
35 * @param lessThan <code>true</code> to select the nearest even spacing <=
\r
36 * value or <code>false</code> to select the nearest even spacing >=
\r
38 * @return the calculated nearest even grid spacing
\r
40 public static double getEvenGridSpacing(double value, double gridSize, boolean lessThan) {
\r
41 double exp = Math.floor(Math.log10(value));
\r
42 double gs = Math.pow(10.0, exp) * gridSize;
\r
43 // System.out.println("getEvenGridSpacing(" + value + ", " + gridSize + ", " + lessThan + "): " + exp + ", " + gs);
\r
44 int i = lessThan ? 1 : 0;
\r
45 int max = lessThan ? gridLineEvenSpacings.length : gridLineEvenSpacings.length - 1;
\r
47 // System.out.println("COMPARE(" + gridLineEvenSpacings[i] + "): " + gridLineEvenSpacings[i]*gs + " >= " + value);
\r
48 if (gridLineEvenSpacings[i] * gs >= value) {
\r
55 // FIXME: this is a workaround to keep the next line from causing an NPE
\r
56 // Need to check the calculations and make some sense into this code once
\r
57 // again to be sure.
\r
58 if (i >= gridLineEvenSpacings.length)
\r
59 return 2 * gridLineEvenSpacings[gridLineEvenSpacings.length - 1] * gs;
\r
60 return gridLineEvenSpacings[i] * gs;
\r
64 * Returns next even grid spacing for value with the assumed grid size of
\r
67 * @param value to round to nearest even grid spacing
\r
68 * @param lessThan <code>true</code> to select the nearest even spacing <=
\r
69 * value or <code>false</code> to select the nearest even spacing >=
\r
71 * @return the calculated nearest even grid spacing
\r
73 public static double getEvenGridSpacing(double value, boolean lessThan) {
\r
74 return getEvenGridSpacing(value, 1.0, lessThan);
\r
78 * Returns next even number for value and exponent of the value.
\r
80 * @param value in units
\r
81 * @param array of at least two elements where the results will be put
\r
82 * @return the specified array, where even number is element [0] and
\r
83 * exponent is element [1]
\r
85 public static double[] getEvenGridSpacingWithExp(double value, double[] array) {
\r
87 throw new NullPointerException("null array");
\r
88 if (array.length < 2)
\r
89 throw new NullPointerException("");
\r
91 /* TODO Time-Spacing
\r
97 double sig = Math.signum( value );
\r
98 double exp = Math.floor(Math.log10( Math.abs(value) ));
\r
99 double gs = Math.pow(10.0, exp);
\r
101 while (i < gridLineEvenSpacings.length - 1) {
\r
102 if (gridLineEvenSpacings[i] * gs >= value) {
\r
107 array[0] = gridLineEvenSpacings[i] * gs * sig;
\r
113 * Returns next even number for value and exponent of the value.
\r
115 * @param value in units
\r
116 * @return array where even number is [0] element and exponent is [1]
\r
119 public static double[] getEvenGridSpacingWithExp(double value) {
\r
120 return getEvenGridSpacingWithExp(value, new double[2]);
\r
125 * @param gridSpacing
\r
128 public static double distanceToNextGridCoord(double fromCoord, double gridSpacing) {
\r
129 double mod = Math.IEEEremainder(fromCoord, gridSpacing);
\r
132 } else if (mod > 0) {
\r
133 return (gridSpacing - mod);
\r
140 * @param gridSpacing
\r
143 public static double distanceToPrevGridCoord(double fromCoord, double gridSpacing) {
\r
144 double mod = Math.IEEEremainder(fromCoord, gridSpacing);
\r
146 return (gridSpacing + mod);
\r
147 } else if (mod > 0) {
\r
155 * @param gridSpacing
\r
159 public static double distanceToNextGridCoordScaled(double coord, double gridSpacing, double scale) {
\r
160 double result = distanceToNextGridCoord(coord, gridSpacing);
\r
161 return result * scale;
\r
166 * @param gridSpacing
\r
170 public static double distanceToPrevGridCoordScaled(double coord, double gridSpacing, double scale) {
\r
171 double result = distanceToPrevGridCoord(coord, gridSpacing);
\r
172 return result * scale;
\r
177 * @param gridSpacing
\r
180 public static double distanceToNearestGridCoord(double coord, double gridSpacing) {
\r
181 double dist = GridUtils.distanceToNextGridCoord(coord, gridSpacing);
\r
182 if (dist > gridSpacing / 2)
\r
183 dist = dist - gridSpacing;
\r
189 * @param gridSpacing
\r
191 public static void snapToGrid(AffineTransform tr, double gridSpacing) {
\r
192 double gdx = GridUtils.distanceToNearestGridCoord(tr.getTranslateX(), gridSpacing);
\r
193 double gdy = GridUtils.distanceToNearestGridCoord(tr.getTranslateY(), gridSpacing);
\r
194 //System.out.println("SNAP TO GRID: delta=(" + gdx + ", " + gdy + "), tr = " + tr);
\r
195 tr.translate(gdx, gdy);
\r
200 * @param gridSpacing
\r
202 public static void snapToGrid(Point2D p, double gridSpacing) {
\r
203 snapToGrid(p, gridSpacing, gridSpacing);
\r
208 * @param gridXSpacing
\r
209 * @param gridYSpacing
\r
211 public static void snapToGrid(Point2D p, double gridXSpacing, double gridYSpacing) {
\r
212 double x = p.getX();
\r
213 double y = p.getY();
\r
214 double gdx = GridUtils.distanceToNearestGridCoord(x, gridXSpacing);
\r
215 double gdy = GridUtils.distanceToNearestGridCoord(y, gridYSpacing);
\r
216 p.setLocation(x + gdx, y + gdy);
\r
221 * @param gridSpacing
\r
224 public static double snapToGrid(double t, double gridSpacing) {
\r
225 double dt = GridUtils.distanceToNearestGridCoord(t, gridSpacing);
\r
230 * Returns an even grid spacing where initialValue*scale <= limit.
\r
232 * @param initialValue
\r
236 * @param lessThan <code>true</code> to select the nearest even spacing <=
\r
237 * limit/scale or <code>false</code> to select the nearest even spacing >=
\r
241 public static double limitedEvenGridSpacing(double initialValue, double scale, double limit, double gridSize, boolean lessThan) {
\r
242 while (initialValue * scale > limit)
\r
244 return getEvenGridSpacing(initialValue, gridSize, lessThan);
\r
248 * Returns an even grid spacing where initialValue*scale <= limit
\r
250 * @param initialValue
\r
253 * @param lessThan <code>true</code> to select the nearest even spacing <=
\r
254 * limit/scale or <code>false</code> to select the nearest even spacing >=
\r
258 public static double limitedEvenGridSpacing(double initialValue, double scale, double limit, boolean lessThan) {
\r
259 return limitedEvenGridSpacing(initialValue, scale, limit, 1.0, lessThan);
\r
263 * A simple test for these routines.
\r
265 public static void main(String[] args) {
\r
266 System.out.println(Arrays.toString(getEvenGridSpacingWithExp(15)));
\r
267 System.out.println(Arrays.toString(getEvenGridSpacingWithExp(16.3)));
\r
268 System.out.println(Arrays.toString(getEvenGridSpacingWithExp(143.41)));
\r
269 System.out.println(Arrays.toString(getEvenGridSpacingWithExp(500.0)));
\r
270 System.out.println(Arrays.toString(getEvenGridSpacingWithExp(10000.0)));
\r
271 System.out.println(Arrays.toString(getEvenGridSpacingWithExp(0.5)));
\r
273 //double aa[] = new double[2];
\r
274 System.out.println(getEvenGridSpacing(15, true));
\r
275 System.out.println(getEvenGridSpacing(15, false));
\r
276 System.out.println(getEvenGridSpacing(16.3, true));
\r
277 System.out.println(getEvenGridSpacing(16.3, false));
\r
278 System.out.println(getEvenGridSpacing(143.41, true));
\r
279 System.out.println(getEvenGridSpacing(143.41, false));
\r
280 System.out.println(getEvenGridSpacing(500.0, true));
\r
281 System.out.println(getEvenGridSpacing(500.0, false));
\r
282 System.out.println(getEvenGridSpacing(10000.0, true));
\r
283 System.out.println(getEvenGridSpacing(10000.0, false));
\r
284 System.out.println(getEvenGridSpacing(0.5, true));
\r
285 System.out.println(getEvenGridSpacing(0.5, false));
\r
286 System.out.println(getEvenGridSpacing(0.045, true));
\r
287 System.out.println(getEvenGridSpacing(0.045, false));
\r
288 System.out.println(getEvenGridSpacing(0.000605, true));
\r
289 System.out.println(getEvenGridSpacing(0.000605, false));
\r
291 System.out.println(getEvenGridSpacing(143, 2.54, true));
\r
292 System.out.println(getEvenGridSpacing(143, 2.54, false));
\r