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
|
/*
* Copyright 2011 Phil Burk, Mobileer Inc
*
* 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.
*/
package com.jsyn.swing;
/**
* Maps integer range info to a double value along an exponential scale.
*
* <pre>
*
* x = ival / resolution
* f(x) = a*(rootˆcx) + b
* f(0.0) = dmin
* f(1.0) = dmax
* b = dmin - a
* a = (dmax - dmin) / (rootˆc - 1)
*
* Inverse function:
* x = log( (y-b)/a ) / log(root)
*
* </pre>
*
* @author Phil Burk, (C) 2011 Mobileer Inc
*/
public class ExponentialRangeModel extends DoubleBoundedRangeModel {
private static final long serialVersionUID = -142785624892302160L;
double a = 1.0;
double b = -1.0;
double span = 1.0;
double root = 10.0;
/** Use default root of 10.0 and span of 1.0. */
public ExponentialRangeModel(String name, int resolution, double dmin, double dmax, double dval) {
this(name, resolution, dmin, dmax, dval, 1.0);
}
/** Set span before setting double value so it is translated correctly. */
ExponentialRangeModel(String name, int resolution, double dmin, double dmax, double dval,
double span) {
super(name, resolution, dmin, dmax, dval);
setRoot(10.0);
setSpan(span);
/* Set again after coefficients setup. */
setDoubleValue(dval);
}
private void updateCoefficients() {
a = (getDoubleMaximum() - getDoubleMinimum()) / (Math.pow(root, span) - 1.0);
b = getDoubleMinimum() - a;
}
private void setRoot(double w) {
root = w;
updateCoefficients();
}
public double getRoot() {
return root;
}
public void setSpan(double c) {
this.span = c;
updateCoefficients();
}
public double getSpan() {
return span;
}
@Override
public double sliderToDouble(int sliderValue) {
updateCoefficients(); // TODO optimize when we call this
double x = (double) sliderValue / getMaximum();
return (a * Math.pow(root, span * x)) + b;
}
@Override
public int doubleToSlider(double dval) {
updateCoefficients(); // TODO optimize when we call this
double z = (dval - b) / a;
double x = Math.log(z) / (span * Math.log(root));
return (int) Math.round(x * getMaximum());
}
public void test(int sliderValue) {
double dval = sliderToDouble(sliderValue);
int ival = doubleToSlider(dval);
}
}
|