1 package net.sf.openrocket.unit;
3 import static net.sf.openrocket.util.Chars.*;
4 import static net.sf.openrocket.util.MathUtil.pow2;
6 import java.util.ArrayList;
7 import java.util.Collections;
8 import java.util.HashMap;
10 import java.util.regex.Matcher;
11 import java.util.regex.Pattern;
13 import net.sf.openrocket.rocketcomponent.Configuration;
14 import net.sf.openrocket.rocketcomponent.Rocket;
18 * A group of units (eg. length, mass etc.). Contains a list of different units of a same
21 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
24 public class UnitGroup {
26 public static final UnitGroup UNITS_NONE;
28 public static final UnitGroup UNITS_MOTOR_DIMENSIONS;
29 public static final UnitGroup UNITS_LENGTH;
30 public static final UnitGroup UNITS_DISTANCE;
32 public static final UnitGroup UNITS_AREA;
33 public static final UnitGroup UNITS_STABILITY;
35 * This unit group contains only the caliber unit that never scales the originating "SI" value.
36 * It can be used in cases where the originating value is already in calibers to obtains the correct unit.
38 public static final UnitGroup UNITS_STABILITY_CALIBERS;
39 public static final UnitGroup UNITS_VELOCITY;
40 public static final UnitGroup UNITS_WINDSPEED;
41 public static final UnitGroup UNITS_ACCELERATION;
42 public static final UnitGroup UNITS_MASS;
43 public static final UnitGroup UNITS_INERTIA;
44 public static final UnitGroup UNITS_ANGLE;
45 public static final UnitGroup UNITS_DENSITY_BULK;
46 public static final UnitGroup UNITS_DENSITY_SURFACE;
47 public static final UnitGroup UNITS_DENSITY_LINE;
48 public static final UnitGroup UNITS_FORCE;
49 public static final UnitGroup UNITS_IMPULSE;
51 /** Time in the order of less than a second (time step etc). */
52 public static final UnitGroup UNITS_TIME_STEP;
54 /** Time in the order of seconds (motor delay etc). */
55 public static final UnitGroup UNITS_SHORT_TIME;
57 /** Time in the order of the flight time of a rocket. */
58 public static final UnitGroup UNITS_FLIGHT_TIME;
59 public static final UnitGroup UNITS_ROLL;
60 public static final UnitGroup UNITS_TEMPERATURE;
61 public static final UnitGroup UNITS_PRESSURE;
62 public static final UnitGroup UNITS_RELATIVE;
63 public static final UnitGroup UNITS_ROUGHNESS;
65 public static final UnitGroup UNITS_COEFFICIENT;
67 // public static final UnitGroup UNITS_FREQUENCY;
70 public static final Map<String, UnitGroup> UNITS;
74 * Note: Units may not use HTML tags.
76 * The scaling value "X" is obtained by "one of this unit is X of SI units"
77 * Type into Google for example: "1 in^2 in m^2"
80 UNITS_NONE = new UnitGroup();
81 UNITS_NONE.addUnit(Unit.NOUNIT2);
83 UNITS_LENGTH = new UnitGroup();
84 UNITS_LENGTH.addUnit(new GeneralUnit(0.001, "mm"));
85 UNITS_LENGTH.addUnit(new GeneralUnit(0.01, "cm"));
86 UNITS_LENGTH.addUnit(new GeneralUnit(1, "m"));
87 UNITS_LENGTH.addUnit(new GeneralUnit(0.0254, "in"));
88 UNITS_LENGTH.addUnit(new FractionalUnit(0.0254, "in/64", "in", 64, 1d / 16d, 0.5d / 64d));
89 UNITS_LENGTH.addUnit(new GeneralUnit(0.3048, "ft"));
90 UNITS_LENGTH.setDefaultUnit(1);
92 UNITS_MOTOR_DIMENSIONS = new UnitGroup();
93 UNITS_MOTOR_DIMENSIONS.addUnit(new GeneralUnit(0.001, "mm"));
94 UNITS_MOTOR_DIMENSIONS.addUnit(new GeneralUnit(0.01, "cm"));
95 UNITS_MOTOR_DIMENSIONS.addUnit(new GeneralUnit(0.0254, "in"));
96 UNITS_MOTOR_DIMENSIONS.setDefaultUnit(0);
98 UNITS_DISTANCE = new UnitGroup();
99 UNITS_DISTANCE.addUnit(new GeneralUnit(1, "m"));
100 UNITS_DISTANCE.addUnit(new GeneralUnit(1000, "km"));
101 UNITS_DISTANCE.addUnit(new GeneralUnit(0.3048, "ft"));
102 UNITS_DISTANCE.addUnit(new GeneralUnit(0.9144, "yd"));
103 UNITS_DISTANCE.addUnit(new GeneralUnit(1609.344, "mi"));
104 UNITS_DISTANCE.addUnit(new GeneralUnit(1852, "nmi"));
106 UNITS_AREA = new UnitGroup();
107 UNITS_AREA.addUnit(new GeneralUnit(pow2(0.001), "mm" + SQUARED));
108 UNITS_AREA.addUnit(new GeneralUnit(pow2(0.01), "cm" + SQUARED));
109 UNITS_AREA.addUnit(new GeneralUnit(1, "m" + SQUARED));
110 UNITS_AREA.addUnit(new GeneralUnit(pow2(0.0254), "in" + SQUARED));
111 UNITS_AREA.addUnit(new GeneralUnit(pow2(0.3048), "ft" + SQUARED));
112 UNITS_AREA.setDefaultUnit(1);
115 UNITS_STABILITY = new UnitGroup();
116 UNITS_STABILITY.addUnit(new GeneralUnit(0.001, "mm"));
117 UNITS_STABILITY.addUnit(new GeneralUnit(0.01, "cm"));
118 UNITS_STABILITY.addUnit(new GeneralUnit(0.0254, "in"));
119 UNITS_STABILITY.addUnit(new CaliberUnit((Rocket) null));
120 UNITS_STABILITY.setDefaultUnit(3);
122 UNITS_STABILITY_CALIBERS = new UnitGroup();
123 UNITS_STABILITY_CALIBERS.addUnit(new GeneralUnit(1, "cal"));
126 UNITS_VELOCITY = new UnitGroup();
127 UNITS_VELOCITY.addUnit(new GeneralUnit(1, "m/s"));
128 UNITS_VELOCITY.addUnit(new GeneralUnit(1 / 3.6, "km/h"));
129 UNITS_VELOCITY.addUnit(new GeneralUnit(0.3048, "ft/s"));
130 UNITS_VELOCITY.addUnit(new GeneralUnit(0.44704, "mph"));
132 UNITS_WINDSPEED = new UnitGroup();
133 UNITS_WINDSPEED.addUnit(new GeneralUnit(1, "m/s"));
134 UNITS_WINDSPEED.addUnit(new GeneralUnit(1 / 3.6, "km/h"));
135 UNITS_WINDSPEED.addUnit(new GeneralUnit(0.3048, "ft/s"));
136 UNITS_WINDSPEED.addUnit(new GeneralUnit(0.44704, "mph"));
138 UNITS_ACCELERATION = new UnitGroup();
139 UNITS_ACCELERATION.addUnit(new GeneralUnit(1, "m/s" + SQUARED));
140 UNITS_ACCELERATION.addUnit(new GeneralUnit(0.3048, "ft/s" + SQUARED));
141 UNITS_ACCELERATION.addUnit(new GeneralUnit(9.80665, "G"));
143 UNITS_MASS = new UnitGroup();
144 UNITS_MASS.addUnit(new GeneralUnit(0.001, "g"));
145 UNITS_MASS.addUnit(new GeneralUnit(1, "kg"));
146 UNITS_MASS.addUnit(new GeneralUnit(0.0283495231, "oz"));
147 UNITS_MASS.addUnit(new GeneralUnit(0.45359237, "lb"));
149 UNITS_INERTIA = new UnitGroup();
150 UNITS_INERTIA.addUnit(new GeneralUnit(0.0001, "kg" + DOT + "cm" + SQUARED));
151 UNITS_INERTIA.addUnit(new GeneralUnit(1, "kg" + DOT + "m" + SQUARED));
152 UNITS_INERTIA.addUnit(new GeneralUnit(1.82899783e-5, "oz" + DOT + "in" + SQUARED));
153 UNITS_INERTIA.addUnit(new GeneralUnit(0.000292639653, "lb" + DOT + "in" + SQUARED));
154 UNITS_INERTIA.addUnit(new GeneralUnit(0.0421401101, "lb" + DOT + "ft" + SQUARED));
155 UNITS_INERTIA.addUnit(new GeneralUnit(1.35581795, "lbf" + DOT + "ft" + DOT + "s" + SQUARED));
156 UNITS_INERTIA.setDefaultUnit(1);
158 UNITS_ANGLE = new UnitGroup();
159 UNITS_ANGLE.addUnit(new DegreeUnit());
160 UNITS_ANGLE.addUnit(new FixedPrecisionUnit("rad", 0.01));
161 UNITS_ANGLE.addUnit(new GeneralUnit(1.0 / 3437.74677078, "arcmin"));
163 UNITS_DENSITY_BULK = new UnitGroup();
164 UNITS_DENSITY_BULK.addUnit(new GeneralUnit(1000, "g/cm" + CUBED));
165 UNITS_DENSITY_BULK.addUnit(new GeneralUnit(1000, "kg/dm" + CUBED));
166 UNITS_DENSITY_BULK.addUnit(new GeneralUnit(1, "kg/m" + CUBED));
167 UNITS_DENSITY_BULK.addUnit(new GeneralUnit(1729.99404, "oz/in" + CUBED));
168 UNITS_DENSITY_BULK.addUnit(new GeneralUnit(16.0184634, "lb/ft" + CUBED));
170 UNITS_DENSITY_SURFACE = new UnitGroup();
171 UNITS_DENSITY_SURFACE.addUnit(new GeneralUnit(10, "g/cm" + SQUARED));
172 UNITS_DENSITY_SURFACE.addUnit(new GeneralUnit(0.001, "g/m" + SQUARED));
173 UNITS_DENSITY_SURFACE.addUnit(new GeneralUnit(1, "kg/m" + SQUARED));
174 UNITS_DENSITY_SURFACE.addUnit(new GeneralUnit(43.9418487, "oz/in" + SQUARED));
175 UNITS_DENSITY_SURFACE.addUnit(new GeneralUnit(0.305151727, "oz/ft" + SQUARED));
176 UNITS_DENSITY_SURFACE.addUnit(new GeneralUnit(4.88242764, "lb/ft" + SQUARED));
177 UNITS_DENSITY_SURFACE.setDefaultUnit(1);
179 UNITS_DENSITY_LINE = new UnitGroup();
180 UNITS_DENSITY_LINE.addUnit(new GeneralUnit(0.001, "g/m"));
181 UNITS_DENSITY_LINE.addUnit(new GeneralUnit(1, "kg/m"));
182 UNITS_DENSITY_LINE.addUnit(new GeneralUnit(0.0930102465, "oz/ft"));
184 UNITS_FORCE = new UnitGroup();
185 UNITS_FORCE.addUnit(new GeneralUnit(1, "N"));
186 UNITS_FORCE.addUnit(new GeneralUnit(4.44822162, "lbf"));
187 UNITS_FORCE.addUnit(new GeneralUnit(9.80665, "kgf"));
189 UNITS_IMPULSE = new UnitGroup();
190 UNITS_IMPULSE.addUnit(new GeneralUnit(1, "Ns"));
191 UNITS_IMPULSE.addUnit(new GeneralUnit(4.44822162, "lbf" + DOT + "s"));
193 UNITS_TIME_STEP = new UnitGroup();
194 UNITS_TIME_STEP.addUnit(new FixedPrecisionUnit("ms", 1, 0.001));
195 UNITS_TIME_STEP.addUnit(new FixedPrecisionUnit("s", 0.01));
196 UNITS_TIME_STEP.setDefaultUnit(1);
198 UNITS_SHORT_TIME = new UnitGroup();
199 UNITS_SHORT_TIME.addUnit(new GeneralUnit(1, "s"));
201 UNITS_FLIGHT_TIME = new UnitGroup();
202 UNITS_FLIGHT_TIME.addUnit(new GeneralUnit(1, "s"));
203 UNITS_FLIGHT_TIME.addUnit(new GeneralUnit(60, "min"));
205 UNITS_ROLL = new UnitGroup();
206 UNITS_ROLL.addUnit(new GeneralUnit(1, "rad/s"));
207 UNITS_ROLL.addUnit(new GeneralUnit(2 * Math.PI, "r/s"));
208 UNITS_ROLL.addUnit(new GeneralUnit(2 * Math.PI / 60, "rpm"));
209 UNITS_ROLL.setDefaultUnit(1);
211 UNITS_TEMPERATURE = new UnitGroup();
212 UNITS_TEMPERATURE.addUnit(new FixedPrecisionUnit("K", 1));
213 UNITS_TEMPERATURE.addUnit(new TemperatureUnit(1, 273.15, DEGREE + "C"));
214 UNITS_TEMPERATURE.addUnit(new TemperatureUnit(5.0 / 9.0, 459.67, DEGREE + "F"));
215 UNITS_TEMPERATURE.setDefaultUnit(1);
217 UNITS_PRESSURE = new UnitGroup();
218 UNITS_PRESSURE.addUnit(new FixedPrecisionUnit("mbar", 1, 1.0e2));
219 UNITS_PRESSURE.addUnit(new FixedPrecisionUnit("bar", 0.001, 1.0e5));
220 UNITS_PRESSURE.addUnit(new FixedPrecisionUnit("atm", 0.001, 1.01325e5));
221 UNITS_PRESSURE.addUnit(new GeneralUnit(101325.0 / 760.0, "mmHg"));
222 UNITS_PRESSURE.addUnit(new GeneralUnit(3386.389, "inHg"));
223 UNITS_PRESSURE.addUnit(new GeneralUnit(6894.75729, "psi"));
224 UNITS_PRESSURE.addUnit(new GeneralUnit(1, "Pa"));
226 UNITS_RELATIVE = new UnitGroup();
227 UNITS_RELATIVE.addUnit(new FixedPrecisionUnit("" + ZWSP, 0.01, 1.0));
228 UNITS_RELATIVE.addUnit(new GeneralUnit(0.01, "%"));
229 UNITS_RELATIVE.addUnit(new FixedPrecisionUnit("" + PERMILLE, 1, 0.001));
230 // UNITS_RELATIVE.addUnit(new FixedPrecisionUnit("" + ZWSP, 0.01, 1.0));
231 // UNITS_RELATIVE.addUnit(new FixedPrecisionUnit("%", 1, 0.01));
232 // UNITS_RELATIVE.addUnit(new FixedPrecisionUnit("" + PERMILLE, 1, 0.001));
233 UNITS_RELATIVE.setDefaultUnit(1);
236 UNITS_ROUGHNESS = new UnitGroup();
237 UNITS_ROUGHNESS.addUnit(new GeneralUnit(0.000001, MICRO + "m"));
238 UNITS_ROUGHNESS.addUnit(new GeneralUnit(0.0000254, "mil"));
241 UNITS_COEFFICIENT = new UnitGroup();
242 UNITS_COEFFICIENT.addUnit(new FixedPrecisionUnit("" + ZWSP, 0.01)); // zero-width space
245 // This is not used by OpenRocket, and not extensively tested:
246 // UNITS_FREQUENCY = new UnitGroup();
247 // UNITS_FREQUENCY.addUnit(new GeneralUnit(1, "s"));
248 // UNITS_FREQUENCY.addUnit(new GeneralUnit(0.001, "ms"));
249 // UNITS_FREQUENCY.addUnit(new GeneralUnit(0.000001, MICRO + "s"));
250 // UNITS_FREQUENCY.addUnit(new FrequencyUnit(1, "Hz"));
251 // UNITS_FREQUENCY.addUnit(new FrequencyUnit(1000, "kHz"));
252 // UNITS_FREQUENCY.setDefaultUnit(3);
255 HashMap<String, UnitGroup> map = new HashMap<String, UnitGroup>();
256 map.put("NONE", UNITS_NONE);
257 map.put("LENGTH", UNITS_LENGTH);
258 map.put("MOTOR_DIMENSIONS", UNITS_MOTOR_DIMENSIONS);
259 map.put("DISTANCE", UNITS_DISTANCE);
260 map.put("VELOCITY", UNITS_VELOCITY);
261 map.put("ACCELERATION", UNITS_ACCELERATION);
262 map.put("AREA", UNITS_AREA);
263 map.put("STABILITY", UNITS_STABILITY);
264 map.put("MASS", UNITS_MASS);
265 map.put("INERTIA", UNITS_INERTIA);
266 map.put("ANGLE", UNITS_ANGLE);
267 map.put("DENSITY_BULK", UNITS_DENSITY_BULK);
268 map.put("DENSITY_SURFACE", UNITS_DENSITY_SURFACE);
269 map.put("DENSITY_LINE", UNITS_DENSITY_LINE);
270 map.put("FORCE", UNITS_FORCE);
271 map.put("IMPULSE", UNITS_IMPULSE);
272 map.put("TIME_STEP", UNITS_TIME_STEP);
273 map.put("SHORT_TIME", UNITS_SHORT_TIME);
274 map.put("FLIGHT_TIME", UNITS_FLIGHT_TIME);
275 map.put("ROLL", UNITS_ROLL);
276 map.put("TEMPERATURE", UNITS_TEMPERATURE);
277 map.put("PRESSURE", UNITS_PRESSURE);
278 map.put("RELATIVE", UNITS_RELATIVE);
279 map.put("ROUGHNESS", UNITS_ROUGHNESS);
280 map.put("COEFFICIENT", UNITS_COEFFICIENT);
282 UNITS = Collections.unmodifiableMap(map);
285 public static void setDefaultMetricUnits() {
286 UNITS_LENGTH.setDefaultUnit("cm");
287 UNITS_MOTOR_DIMENSIONS.setDefaultUnit("mm");
288 UNITS_DISTANCE.setDefaultUnit("m");
289 UNITS_AREA.setDefaultUnit("cm" + SQUARED);
290 UNITS_STABILITY.setDefaultUnit("cal");
291 UNITS_VELOCITY.setDefaultUnit("m/s");
292 UNITS_ACCELERATION.setDefaultUnit("m/s" + SQUARED);
293 UNITS_MASS.setDefaultUnit("g");
294 UNITS_INERTIA.setDefaultUnit("kg" + DOT + "m" + SQUARED);
295 UNITS_ANGLE.setDefaultUnit("" + DEGREE);
296 UNITS_DENSITY_BULK.setDefaultUnit("g/cm" + CUBED);
297 UNITS_DENSITY_SURFACE.setDefaultUnit("g/m" + SQUARED);
298 UNITS_DENSITY_LINE.setDefaultUnit("g/m");
299 UNITS_FORCE.setDefaultUnit("N");
300 UNITS_IMPULSE.setDefaultUnit("Ns");
301 UNITS_TIME_STEP.setDefaultUnit("s");
302 UNITS_FLIGHT_TIME.setDefaultUnit("s");
303 UNITS_ROLL.setDefaultUnit("r/s");
304 UNITS_TEMPERATURE.setDefaultUnit(DEGREE + "C");
305 UNITS_WINDSPEED.setDefaultUnit("m/s");
306 UNITS_PRESSURE.setDefaultUnit("mbar");
307 UNITS_RELATIVE.setDefaultUnit("%");
308 UNITS_ROUGHNESS.setDefaultUnit(MICRO + "m");
311 public static void setDefaultImperialUnits() {
312 UNITS_LENGTH.setDefaultUnit("in");
313 UNITS_MOTOR_DIMENSIONS.setDefaultUnit("in");
314 UNITS_DISTANCE.setDefaultUnit("ft");
315 UNITS_AREA.setDefaultUnit("in" + SQUARED);
316 UNITS_STABILITY.setDefaultUnit("cal");
317 UNITS_VELOCITY.setDefaultUnit("ft/s");
318 UNITS_ACCELERATION.setDefaultUnit("ft/s" + SQUARED);
319 UNITS_MASS.setDefaultUnit("oz");
320 UNITS_INERTIA.setDefaultUnit("lb" + DOT + "ft" + SQUARED);
321 UNITS_ANGLE.setDefaultUnit("" + DEGREE);
322 UNITS_DENSITY_BULK.setDefaultUnit("oz/in" + CUBED);
323 UNITS_DENSITY_SURFACE.setDefaultUnit("oz/ft" + SQUARED);
324 UNITS_DENSITY_LINE.setDefaultUnit("oz/ft");
325 UNITS_FORCE.setDefaultUnit("N");
326 UNITS_IMPULSE.setDefaultUnit("Ns");
327 UNITS_TIME_STEP.setDefaultUnit("s");
328 UNITS_FLIGHT_TIME.setDefaultUnit("s");
329 UNITS_ROLL.setDefaultUnit("r/s");
330 UNITS_TEMPERATURE.setDefaultUnit(DEGREE + "F");
331 UNITS_WINDSPEED.setDefaultUnit("mph");
332 UNITS_PRESSURE.setDefaultUnit("mbar");
333 UNITS_RELATIVE.setDefaultUnit("%");
334 UNITS_ROUGHNESS.setDefaultUnit("mil");
339 * Return a UnitGroup for stability units based on the rocket.
341 * @param rocket the rocket from which to calculate the caliber
342 * @return the unit group
344 public static UnitGroup stabilityUnits(Rocket rocket) {
345 return new StabilityUnitGroup(rocket);
350 * Return a UnitGroup for stability units based on the rocket configuration.
352 * @param config the rocket configuration from which to calculate the caliber
353 * @return the unit group
355 public static UnitGroup stabilityUnits(Configuration config) {
356 return new StabilityUnitGroup(config);
361 * Return a UnitGroup for stability units based on a constant caliber.
363 * @param reference the constant reference length
364 * @return the unit group
366 public static UnitGroup stabilityUnits(double reference) {
367 return new StabilityUnitGroup(reference);
371 //////////////////////////////////////////////////////
374 protected ArrayList<Unit> units = new ArrayList<Unit>();
375 protected int defaultUnit = 0;
377 public int getUnitCount() {
381 public Unit getDefaultUnit() {
382 return units.get(defaultUnit);
385 public int getDefaultUnitIndex() {
389 public void setDefaultUnit(int n) {
390 if (n < 0 || n >= units.size()) {
391 throw new IllegalArgumentException("index out of range: " + n);
399 * Find a unit by approximate unit name. Only letters and (ordinary) numbers are
400 * considered in the matching. This method is mainly means for testing, allowing
401 * a simple means to obtain a particular unit.
403 * @param str the unit name.
404 * @return the corresponding unit, or <code>null</code> if not found.
406 public Unit findApproximate(String str) {
407 str = str.replaceAll("\\W", "").trim();
408 for (Unit u : units) {
409 String name = u.getUnit().replaceAll("\\W", "").trim();
410 if (str.equalsIgnoreCase(name))
417 * Set the default unit based on the unit name. Throws an exception if a
418 * unit with the provided name is not available.
420 * @param name the unit name.
421 * @throws IllegalArgumentException if the corresponding unit is not found in the group.
423 public void setDefaultUnit(String name) throws IllegalArgumentException {
424 for (int i = 0; i < units.size(); i++) {
425 if (units.get(i).getUnit().equals(name)) {
430 throw new IllegalArgumentException("name=" + name);
433 public Unit getUnit(String name) throws IllegalArgumentException {
434 for (int i = 0; i < units.size(); i++) {
435 if (units.get(i).getUnit().equals(name)) {
439 throw new IllegalArgumentException("name=" + name);
442 public Unit getUnit(int n) {
446 public int getUnitIndex(Unit u) {
447 return units.indexOf(u);
450 public void addUnit(Unit u) {
454 public boolean contains(Unit u) {
455 return units.contains(u);
458 public Unit[] getUnits() {
459 return units.toArray(new Unit[0]);
463 * Return the value in SI units from the default unit of this group.
464 * It is the same as calling <code>getDefaultUnit().fromUnit(value)</code>
466 * @param value the default unit value to convert
467 * @return the value in SI units.
468 * @see Unit#fromUnit(double)
470 public double fromUnit( double value ) {
471 return this.getDefaultUnit().fromUnit(value);
475 * Return the value formatted by the default unit of this group.
476 * It is the same as calling <code>getDefaultUnit().toString(value)</code>.
478 * @param value the SI value to format.
479 * @return the formatted string.
480 * @see Unit#toString(double)
482 public String toString(double value) {
483 return this.getDefaultUnit().toString(value);
488 * Return the value formatted by the default unit of this group including the unit.
489 * It is the same as calling <code>getDefaultUnit().toStringUnit(value)</code>.
491 * @param value the SI value to format.
492 * @return the formatted string.
493 * @see Unit#toStringUnit(double)
495 public String toStringUnit(double value) {
496 return this.getDefaultUnit().toStringUnit(value);
504 * Creates a new Value object with the specified value and the default unit of this group.
506 * @param value the value to set.
507 * @return a new Value object.
509 public Value toValue(double value) {
510 return this.getDefaultUnit().toValue(value);
516 private static final Pattern STRING_PATTERN = Pattern.compile("^\\s*([0-9.,-]+)(.*?)$");
519 * Converts a string into an SI value. If the string has one of the units in this
520 * group appended to it, that unit will be used in conversion. Otherwise the default
521 * unit will be used. If an unknown unit is specified or the value does not parse
522 * with <code>Double.parseDouble</code> then a <code>NumberFormatException</code>
525 * This method is applicable only for simple units without e.g. powers.
527 * @param str the string to parse.
528 * @return the SI value.
529 * @throws NumberFormatException if the string cannot be parsed.
531 public double fromString(String str) {
532 Matcher matcher = STRING_PATTERN.matcher(str);
534 if (!matcher.matches()) {
535 throw new NumberFormatException("string did not match required pattern");
538 double value = Double.parseDouble(matcher.group(1));
539 String unit = matcher.group(2).trim();
541 if (unit.equals("")) {
542 value = this.getDefaultUnit().fromUnit(value);
545 for (i = 0; i < units.size(); i++) {
546 Unit u = units.get(i);
547 if (unit.equalsIgnoreCase(u.getUnit())) {
548 value = u.fromUnit(value);
552 if (i >= units.size()) {
553 throw new NumberFormatException("unknown unit " + unit);
561 ///////////////////////////
565 * A private class that switches the CaliberUnit to a rocket-specific CaliberUnit.
566 * All other methods are passed through to UNITS_STABILITY.
568 private static class StabilityUnitGroup extends UnitGroup {
570 public StabilityUnitGroup(double ref) {
571 this(new CaliberUnit(ref));
574 public StabilityUnitGroup(Rocket rocket) {
575 this(new CaliberUnit(rocket));
578 public StabilityUnitGroup(Configuration config) {
579 this(new CaliberUnit(config));
582 private StabilityUnitGroup(CaliberUnit caliberUnit) {
583 this.units.addAll(UnitGroup.UNITS_STABILITY.units);
584 this.defaultUnit = UnitGroup.UNITS_STABILITY.defaultUnit;
585 for (int i = 0; i < units.size(); i++) {
586 if (units.get(i) instanceof CaliberUnit) {
587 units.set(i, caliberUnit);
594 public void setDefaultUnit(int n) {
595 super.setDefaultUnit(n);
596 UNITS_STABILITY.setDefaultUnit(n);