/*
* NumberSpace.java
* JCollider
*
* Copyright (c) 2004-2010 Hanns Holger Rutz. All rights reserved.
*
* This software is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either
* version 2, june 1991 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License (gpl.txt) along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* For further information, please contact Hanns Holger Rutz at
* contact@sciss.de
*
*
* Changelog:
* 29-Jul-06 copied from de.sciss.util.NumberSpace
*/
//package de.sciss.util;
package de.sciss.jcollider.gui;
/**
* A number space
* describes a field of possible
* numeric values with a minimum
* and maximum (which can be infinity),
* a central value (usually zero)
* a quantization size which can be
* used to describe integers or to
* limit the numeric resolution.
*
* @author Hanns Holger Rutz
* @version 0.25, 17-Sep-05
*/
public class NumberSpace
{
/**
* Minimum allowed value
* or Double.NEGATIVE_INFINITY
*/
public final double min;
/**
* Maximum allowed value
* or Double.POSITIVE_INFINITY
*/
public final double max;
/**
* Quantization of values
* or zero
*/
public final double quant;
/**
* Reset value, i.e.
* a kind of default value.
*/
public final double reset;
/**
*/
public final int minFracDigits;
/**
*/
public final int maxFracDigits;
/**
* Ready-made NumberField for
* double values, without boundaries.
*/
public static NumberSpace genericDoubleSpace = new NumberSpace(
Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 0.0 );
/**
* Ready-made NumberField for
* integer values, without boundaries.
*/
public static NumberSpace genericIntSpace = new NumberSpace(
Integer.MIN_VALUE, Integer.MAX_VALUE, 1.0 );
private final boolean isInteger;
/**
* Creates a new <code>NumberSpace</code>
* with the given values.
*
* @param min minimum allowed value or a special value like Double.NEGATIVE_INFINITY
* or Integer.MIN_VALUE
* @param max maximum allowed value or a special value like Float.POSITIVE_INFINITY
* or Long.MAX_VALUE
* @param quant coarsity for each allowed value. E.g. if quant is 0.1, then a
* value of 0.12 becomes 0.1 if you call fitValue. If quant is 0.0,
* no quantization is used. If quant is integer, the number space is
* marked integer and calling isInteger returns true.
* @param reset central value for initializations of unknown values. Usually zero.
*/
public NumberSpace( double min, double max, double quant, int minFracDigits, int maxFracDigits, double reset )
{
this.min = min;
this.max = max;
this.quant = quant;
this.reset = reset;
this.minFracDigits = minFracDigits;
this.maxFracDigits = maxFracDigits;
isInteger = quant > 0.0 && (quant % 1.0) == 0.0;
}
/**
* Creates a new NumberSpace
* with the given values. Reset is
* zero or on of min/max,
* increment is max( 1, quant )
*/
public NumberSpace( double min, double max, double quant, int minFracDigits, int maxFracDigits )
{
this( min, max, quant, minFracDigits, maxFracDigits, NumberSpace.fitValue( 0.0, min, max, quant ));
}
/**
* Creates a new NumberSpace
* with the given values. Reset is
* zero or on of min/max,
* increment is max( 1, quant )
*/
public NumberSpace( double min, double max, double quant )
{
this( min, max, quant, Math.max( 1, NumberSpace.fracDigitsFromQuant( quant )),
Math.min( 2, NumberSpace.fracDigitsFromQuant( quant )));
}
public static int fracDigitsFromQuant( double quant )
{
if( quant > 0.0 ) {
int maxFracDigits = 0;
while( (quant % 1.0) != 0.0 ) {
maxFracDigits++;
quant *= 10;
}
return maxFracDigits;
} else {
return Integer.MAX_VALUE;
}
}
/**
* States if the NumberSpace's quant
* is integer (and not zero).
*
* @return true if the quantization is integer and
* hence all valid values are integers
*/
public boolean isInteger()
{
return isInteger;
}
/**
* Utility method for creating a generic integer space
* for a given minimum and maximum value. Quant will
* be set to 1.0.
*/
public static NumberSpace createIntSpace( int min, int max )
{
return new NumberSpace( min, max, 1.0 );
}
/**
* Validates a value for this number space. First,
* it is quantized (rounded) if necessary. Then it
* is limited to the minimum and maximum value.
*
* @param value a value to validate
* @return the input value possibly quantisized and limited
* the space's bounds.
*/
public double fitValue( double value )
{
if( quant > 0.0 ) {
value = Math.round( value / quant ) * quant;
}
return Math.min( max, Math.max( min, value ));
}
/**
* Validates a value for an ad-hoc number space. First,
* it is quantized (rounded) if necessary. Then it
* is limited to the minimum and maximum value.
*
* @param value a value to validate
* @param min the minimum limitation
* @param max the maximum limitation
* @param quant the quantization to apply
* @return the input value possibly quantisized and limited
* the described space's bounds.
*/
public static double fitValue( double value, double min, double max, double quant )
{
if( quant > 0.0 ) {
value = Math.round( value / quant ) * quant;
}
return Math.min( max, Math.max( min, value ));
}
}