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