summaryrefslogtreecommitdiff
path: root/java/src/org/singinst/uf/presenter/LineBounds.java
blob: 1fbb267999bd461e1c240572ac3d280b4c31611a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package org.singinst.uf.presenter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

import org.singinst.uf.math.InvertableFunction;
import org.singinst.uf.math.MathUtil;

public class LineBounds implements LineBounded {
	private final double first;
	private final double second;
	private final boolean displayAsLog;

	public LineBounds(double first, double second) {
		this(first, second, false);
	}

	public LineBounds(double first, double second, boolean displayAsLog) {
		if (first == second) {
			throw new IllegalArgumentException();
		}
		this.first = first;
		this.second = second;
		this.displayAsLog = displayAsLog;
	}

	public double getLength() {
		return getSecond() - getFirst();
	}

	public double getLowerBound() {
		return getFirst();
	}

	public double getUpperBound() {
		return getSecond();
	}

	public LineBounds getLineBounds() {
		return this;
	}

	public double getMidpoint() {
		return constrain((getLowerBound() + getUpperBound()) / 2);
	}

	public Iterable<Double> getSpanningSamples(int sampleCount) {
		List<Double> samples = new ArrayList<Double>();
		for (int i = 0; i < sampleCount; i++) {
			samples.add(getUpperBound() * i / (sampleCount - 1)
					+ getLowerBound() * (sampleCount - i - 1) / (sampleCount - 1)
					);
		}
		return samples;
	}

	public Iterable<Double> getVisualSamples(int maxSamples, double start, Collection<Double> requiredPoints) {
		double sampleSizeLowerBound = getLength() / maxSamples;
		double sampleSize = Math.pow(10, Math.ceil(Math.log10(sampleSizeLowerBound)));
		SortedSet<Double> samples = new TreeSet<Double>();
		for (double i = start; i <= getUpperBound(); i += sampleSize) {
			samples.add(i);
		}
		for (double i = start - sampleSize; i >= getLowerBound(); i -= sampleSize) {
			samples.add(i);
		}
		samples.addAll(requiredPoints);
		return samples;
	}

	public Iterable<AxisSample> getAxisSamples(boolean majorTick) {
		int maxReadableSamples = majorTick ? 10 : 100;
		List<AxisSample> retVal = new ArrayList<AxisSample>();
		for (double value : getVisualSamples(maxReadableSamples, getLowerBound(), Collections.<Double>emptyList())) {
			if (majorTick) {
				retVal.add(new AxisSample(value, getCanvasString(value)));
			} else {
				retVal.add(new AxisSample(value));				
			}
		}
		return retVal;
	}

	protected CanvasString getCanvasString(double x) {
		if (displayAsLog) {
			return new CanvasString("" + 10, NumericEntry.formatAsScalar(x));
		} else {
			return new CanvasString(NumericEntry.formatAsScalar(x));
		}
	}

	public double getFirst() {
		return first;
	}

	public double getSecond() {
		return second;
	}
	
	public boolean displayAsLog(){
		return displayAsLog;
	}

	public InvertableFunction toDisplay() {
		return InvertableFunction.IDENTITY;
	}

	public String userFormat(double value) {
			return NumericEntry.getScalarFormat().format(value);
	}

	public double constrain(double rounded) {
		return MathUtil.bound(rounded, getFirst(), getSecond());
	}
}