1 package net.sf.openrocket.unit;
3 import java.util.ArrayList;
5 public class GeneralUnit extends Unit {
7 private final int significantNumbers;
8 private final int decimalRounding;
10 // Values smaller that this are rounded using decimal rounding
11 // [pre-calculated as 10^(significantNumbers-1)]
12 private final double decimalLimit;
14 // Pre-calculated as 10^significantNumbers
15 private final double significantNumbersLimit;
18 public GeneralUnit(double multiplier, String unit) {
19 this(multiplier, unit, 2, 10);
22 public GeneralUnit(double multiplier, String unit, int significantNumbers) {
23 this(multiplier, unit, significantNumbers, 10);
26 public GeneralUnit(double multiplier, String unit, int significantNumbers, int decimalRounding) {
27 super(multiplier, unit);
28 assert(significantNumbers>0);
29 assert(decimalRounding>0);
31 this.significantNumbers = significantNumbers;
32 this.decimalRounding = decimalRounding;
36 for (int i=1; i<significantNumbers; i++) {
41 significantNumbersLimit = e;
45 public double round(double value) {
46 if (value < decimalLimit) {
47 // Round to closest 1/decimalRounding
48 return Math.rint(value*decimalRounding)/decimalRounding;
50 // Round to given amount of significant numbers
52 while (value >= significantNumbersLimit) {
56 return Math.rint(value)*m;
63 // TODO: LOW: untested
64 // start, end and scale in this units
66 public ArrayList<Tick> getTicks(double start, double end, double scale) {
67 ArrayList<Tick> ticks = new ArrayList<Tick>();
71 // TODO: LOW: more fine-grained (e.g. 0||||5||||10||||15||||20)
72 if (scale <= 1.0/decimalRounding) {
73 delta = 1.0/decimalRounding;
75 major = decimalRounding;
76 } else if (scale <= 1.0) {
77 delta = 1.0/decimalRounding;
78 normal = decimalRounding;
79 major = decimalRounding*10;
88 major = 100; // TODO: LOW: More fine-grained with 5
91 double v = Math.ceil(start/delta)*delta;
92 int n = (int)Math.round(v/delta);
96 // ticks.add(new Tick(v,Tick.MAJOR));
97 // else if (n%normal == 0)
98 // ticks.add(new Tick(v,Tick.NORMAL));
100 // ticks.add(new Tick(v,Tick.MINOR));
109 public Tick[] getTicks(double start, double end, double minor, double major) {
111 start = toUnit(start);
113 minor = toUnit(minor);
114 major = toUnit(major);
116 if (minor <= 0 || major <= 0 || major < minor) {
117 throw new IllegalArgumentException("getTicks called with minor="+minor+" major="+major);
120 ArrayList<Tick> ticks = new ArrayList<Tick>();
122 int mod2,mod3,mod4; // Moduli for minor-notable, major-nonnotable, major-notable
125 // Find the smallest possible step size
131 // one is the smallest round-ten that is larger than minor
132 if (one/2 >= minor) {
133 // smallest step is round-five
135 mod2 = 2; // Changed later if clashes with major ticks
138 mod2 = 10; // Changed later if clashes with major ticks
141 // Find step size for major ticks
147 if (one/2 >= major) {
148 // major step is round-five, major-notable is next round-ten
149 double majorstep = one/2;
150 mod3 = (int)Math.round(majorstep/minstep);
153 // major step is round-ten, major-notable is next round-ten
154 mod3 = (int)Math.round(one/minstep);
157 // Check for clashes between minor-notable and major-nonnotable
160 mod2 = 1; // Every minor tick is notable
162 mod2 = 5; // Every fifth minor tick is notable
166 // Calculate starting position
167 int pos = (int)Math.ceil(start/minstep);
168 // System.out.println("mod2="+mod2+" mod3="+mod3+" mod4="+mod4);
169 while (pos*minstep <= end) {
170 double unitValue = pos*minstep;
171 double value = fromUnit(unitValue);
174 ticks.add(new Tick(value,unitValue,true,true));
175 else if (pos%mod3 == 0)
176 ticks.add(new Tick(value,unitValue,true,false));
177 else if (pos%mod2 == 0)
178 ticks.add(new Tick(value,unitValue,false,true));
180 ticks.add(new Tick(value,unitValue,false,false));
185 return ticks.toArray(new Tick[0]);
190 public double getNextValue(double value) {
191 // TODO: HIGH: Auto-generated method stub
196 public double getPreviousValue(double value) {
197 // TODO: HIGH: Auto-generated method stub
204 private static void printTicks(double start, double end, double minor, double major) {
205 Tick[] ticks = Unit.NOUNIT2.getTicks(start, end, minor, major);
206 String str = "Ticks for ("+start+","+end+","+minor+","+major+"):";
207 for (int i=0; i<ticks.length; i++) {
208 str += " "+ticks[i].value;
209 if (ticks[i].major) {
210 if (ticks[i].notable)
215 if (ticks[i].notable)
221 System.out.println(str);
223 public static void main(String[] arg) {
224 printTicks(0,100,1,10);
225 printTicks(4.7,11.0,0.15,0.7);