package org.das2.datum;
import java.util.ArrayList;
/**
* A DomainDivider which divides logarithmically (base 10), with linear subdivisions.
* It provides divisions such as
* - 1,2,3,4,5,6,7,8,9,10,20,30,40,50,...
*
- 2,4,6,8,10,20,40,60,80,100,200,...
*
* @author ed
*/
public class LogLinDomainDivider implements DomainDivider {
/**
* linear divisions within the decade 1.0 to 10.0.
*/
private LinearDomainDivider linearDivider;
/**
* create a way to access this class directly.
* @return
*/
public static LogLinDomainDivider create() {
return new LogLinDomainDivider();
}
/**
* create one directly, useful for debugging.
* @param significand 1, 2, or 5.
* @param exponent 0 or -1 for many per cycle.
* @return new LoglinDomainDivider
*/
public static LogLinDomainDivider create( int significand, int exponent ) {
LinearDomainDivider lin= new LinearDomainDivider(significand,exponent);
return new LogLinDomainDivider(lin);
}
protected LogLinDomainDivider() {
this(new LinearDomainDivider());
}
private LogLinDomainDivider(LinearDomainDivider linearDivider) {
this.linearDivider = linearDivider;
int significand= linearDivider.getSignificand();
if ( significand!=1 && significand!=2 && significand!=5 ) {
throw new IllegalArgumentException("significand must be 1, 2, or 5.");
}
}
@Override
public DomainDivider coarserDivider(boolean superset) {
LinearDomainDivider d = (LinearDomainDivider) linearDivider.coarserDivider(superset);
if (d.boundaryCount(Datum.create(1.0), Datum.create(10.0 )) < 1) {
// revert to straight log division
return new LogDomainDivider();
}
else
return new LogLinDomainDivider(d);
}
@Override
public DomainDivider finerDivider(boolean superset) {
// Make the linear subdivision finer.
LinearDomainDivider lin = (LinearDomainDivider)linearDivider.finerDivider(superset);
return new LogLinDomainDivider(lin);
}
@Override
public DatumVector boundaries(Datum min, Datum max) {
if ( !min.isFinite() || !max.isFinite() ) {
System.err.println("min and max must be finite");
// throw new IllegalArgumentException("min and max must be finite" );
}
ArrayList bb= new ArrayList<>();
double decade = Math.pow(10, Math.floor(Math.log10(min.doubleValue())));
double nextDecade= decade*10;
DatumRange current= linearDivider.rangeContaining(min.divide(decade));
current= DatumRange.newRange( current.min().multiply(decade), current.max().multiply(decade) );
Datum m=current.min();
Units u= m.getUnits();
while ( m.le(max) ) {
while ( m.value()