001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032:
033: package com.vividsolutions.jump.geom.precision;
034:
035: /**
036: * Reduces the precision of a number
037: * by rounding it off after scaling by a given scale factor.
038: */
039: public class NumberPrecisionReducer {
040:
041: /**
042: * Computes the scale factor for a given number of decimal places.
043: * A negative value for decimalPlaces indicates the scale factor
044: * should be divided rather than multiplied. The negative sign
045: * is carried through to the computed scale factor.
046: * @param decimalPlaces
047: * @return the scale factor
048: */
049: public static double scaleFactorForDecimalPlaces(int decimalPlaces) {
050: int power = Math.abs(decimalPlaces);
051: int sign = decimalPlaces >= 0 ? 1 : -1;
052: double scaleFactor = 1.0;
053: for (int i = 1; i <= power; i++) {
054: scaleFactor *= 10.0;
055: }
056: return scaleFactor * sign;
057: }
058:
059: private double scaleFactor = 0.0;
060: private boolean multiplyByScaleFactor = true;
061:
062: public NumberPrecisionReducer() {
063: }
064:
065: /**
066: * A negative value for scaleFactor indicates
067: * that the precision reduction will eliminate significant digits
068: * to the left of the decimal point.
069: * (I.e. the scale factor
070: * will be divided rather than multiplied).
071: * A zero value for scaleFactor will result in no precision reduction being performed.
072: * A scale factor is normally an integer value.
073: *
074: * @param scaleFactor
075: */
076: public NumberPrecisionReducer(double scaleFactor) {
077: setScaleFactor(scaleFactor);
078: }
079:
080: public void setScaleFactor(double scaleFactor) {
081: this .scaleFactor = Math.abs(scaleFactor);
082: multiplyByScaleFactor = scaleFactor >= 0;
083: }
084:
085: public double reducePrecision(double d) {
086: // sanity check
087: if (scaleFactor == 0.0)
088: return d;
089:
090: if (multiplyByScaleFactor) {
091: double scaled = d * scaleFactor;
092: return Math.floor(scaled + 0.5) / scaleFactor;
093: } else {
094: double scaled = d / scaleFactor;
095: return Math.floor(scaled + 0.5) * scaleFactor;
096: }
097:
098: }
099:
100: }
|