/******************************************************************************* * Mission Control Technologies, Copyright (c) 2009-2012, United States Government * as represented by the Administrator of the National Aeronautics and Space * Administration. All rights reserved. * * The MCT platform is licensed under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * MCT includes source code licensed under additional open source licenses. See * the MCT Open Source Licenses file included with this distribution or the About * MCT Licenses dialog available at runtime from the MCT Help menu for additional * information. *******************************************************************************/ package plotter; import java.util.Arrays; /** * Default implementation of {@link TickMarkCalculator} for a linear axis. * @author Adam Crume */ public class LinearTickMarkCalculator implements TickMarkCalculator { @Override public double[][] calculateTickMarks(Axis axis) { double start = axis.getStart(); double end = axis.getEnd(); double min = start; double max = end; if(min > max) { double tmp = max; max = min; min = tmp; } double diff = max - min; // d should be diff scaled to between 1 and 10 double d = diff / Math.pow(10, Math.floor(Math.log10(diff))); double adj = .1; while(d < 2) { d *= 2; adj *= 2; } while(d > 5) { d /= 2; adj *= 5; } double spacing = diff / d; double spacing2 = spacing * adj; double[] minorVals; double[] majorVals; if(min >= 0) { // In this case, both ends of the axis are non-negative. Go from min to max. double startCount = Math.ceil(min / spacing); double endCount = Math.floor(max / spacing); majorVals = new double[(int)(endCount - startCount) + 1]; double value = startCount * spacing; for(int i = 0; i < majorVals.length; i++) { majorVals[i] = value; value += spacing; } startCount = Math.ceil(min / spacing2); endCount = Math.floor(max / spacing2); minorVals = new double[(int) (endCount - startCount) + 1]; value = startCount * spacing2; for(int i = 0; i < minorVals.length; i++) { minorVals[i] = value; value += spacing2; } } else if(max <= 0) { // In this case, both ends of the axis are non-positive. Go from max to min. double startCount = Math.floor(max / spacing); double endCount = Math.ceil(min / spacing); majorVals = new double[(int) (startCount - endCount) + 1]; double value = startCount * spacing; for(int i = 0; i < majorVals.length; i++) { majorVals[i] = value; value -= spacing; } startCount = Math.floor(max / spacing2); endCount = Math.ceil(min / spacing2); minorVals = new double[(int) (startCount - endCount) + 1]; value = startCount * spacing2; for(int i = 0; i < minorVals.length; i++) { minorVals[i] = value; value -= spacing2; } } else { // In this case, one end is positive and one is negative. // Start from 0 and go in both directions to minimize rounding error. // Calculate the number of major ticks. There should be a better way. int majorCount = 0; double value = 0; while(value <= max) { value += spacing; majorCount++; } value = -spacing; while(value >= min) { value -= spacing; majorCount++; } majorVals = new double[majorCount]; value = 0; int i = 0; while(value <= max) { majorVals[i] = value; i++; value += spacing; } value = -spacing; while(value >= min) { majorVals[i] = value; i++; value -= spacing; } // Calculate the number of minor ticks. There should be a better way. int minorCount = 0; value = 0; while(value <= max) { value += spacing2; minorCount++; } value = -spacing2; while(value >= min) { value -= spacing2; minorCount++; } minorVals = new double[minorCount]; value = 0; i = 0; while(value <= max) { minorVals[i] = value; i++; value += spacing2; } value = -spacing2; while(value >= min) { minorVals[i] = value; i++; value -= spacing2; } } Arrays.sort(majorVals); return new double[][] {majorVals, minorVals}; } }