Add some NONSI defaults
[sw/motorsim] / src / com / billkuker / rocketry / motorsim / RocketScience.java
1 package com.billkuker.rocketry.motorsim;\r
2 \r
3 import java.lang.reflect.Field;\r
4 import java.lang.reflect.Modifier;\r
5 import java.text.DecimalFormat;\r
6 import java.text.NumberFormat;\r
7 import java.util.HashSet;\r
8 import java.util.Set;\r
9 import java.util.prefs.Preferences;\r
10 \r
11 import javax.measure.quantity.Pressure;\r
12 import javax.measure.quantity.Quantity;\r
13 import javax.measure.unit.NonSI;\r
14 import javax.measure.unit.ProductUnit;\r
15 import javax.measure.unit.SI;\r
16 import javax.measure.unit.Unit;\r
17 import javax.measure.unit.UnitFormat;\r
18 \r
19 import org.jscience.physics.amount.Amount;\r
20 \r
21 public class RocketScience {\r
22         public static Unit<Pressure> PSI = new ProductUnit<Pressure>(NonSI.POUND_FORCE.divide(NonSI.INCH.pow(2)));\r
23         public static Unit<Impulse> NEWTON_SECOND = new ProductUnit<Impulse>(SI.NEWTON.times(SI.SECOND));\r
24         public static Unit<Impulse> POUND_SECOND = new ProductUnit<Impulse>(NonSI.POUND_FORCE.times(SI.SECOND));\r
25         static{\r
26                 UnitFormat.getInstance().label(PSI, "psi");\r
27                 UnitFormat.getInstance().label(NEWTON_SECOND, "Ns");\r
28         }\r
29 \r
30         public interface MolarWeight extends Quantity {\r
31                 public static final Unit<MolarWeight> UNIT = new ProductUnit<MolarWeight>(\r
32                                 SI.KILOGRAM.divide(SI.MOLE));\r
33         }\r
34         \r
35         public interface Impulse extends Quantity {\r
36                 public static Unit<Impulse> UNIT = NEWTON_SECOND;\r
37         }\r
38 \r
39         public static enum UnitPreference{\r
40                 SI(new Unit[]{\r
41                                 javax.measure.unit.SI.MILLIMETER.pow(2),\r
42                                 javax.measure.unit.SI.MILLIMETER,\r
43                                 javax.measure.unit.SI.MILLIMETER.divide(javax.measure.unit.SI.SECOND),\r
44                                 javax.measure.unit.SI.NEWTON,\r
45                                 javax.measure.unit.SI.GRAM,\r
46                                 javax.measure.unit.SI.MEGA(javax.measure.unit.SI.PASCAL),\r
47                                 NEWTON_SECOND\r
48                 }),\r
49                 NONSI(new Unit[]{\r
50                                 javax.measure.unit.NonSI.INCH.pow(2),\r
51                                 javax.measure.unit.NonSI.INCH,\r
52                                 javax.measure.unit.NonSI.POUND_FORCE,\r
53                                 javax.measure.unit.NonSI.OUNCE,\r
54                                 javax.measure.unit.NonSI.INCH.divide(javax.measure.unit.SI.SECOND),\r
55                                 PSI,\r
56                                 POUND_SECOND\r
57                 });\r
58                 \r
59                 private static UnitPreference preference = SI;\r
60 \r
61                 static {\r
62                         Preferences prefs = Preferences.userNodeForPackage(RocketScience.class);\r
63                         String p = prefs.get("PreferedUnits", "SI");\r
64                         preference = UnitPreference.valueOf(p);\r
65                 }\r
66                 \r
67                 public static UnitPreference getUnitPreference(){\r
68                         return preference;\r
69                 }\r
70                 \r
71                 public static void setUnitPreference( final UnitPreference up ){\r
72                         preference = up;\r
73                         Preferences prefs = Preferences.userNodeForPackage(RocketScience.class);\r
74                         prefs.put("PreferedUnits", up.toString());\r
75                 }\r
76                 \r
77                 protected Set<Unit<?>> units = new HashSet<Unit<?>>();\r
78                 \r
79                 UnitPreference( Unit<?> u[] ){\r
80                         for ( Unit<?> uu : u )\r
81                                 units.add(uu);\r
82                 }\r
83                 \r
84                 @SuppressWarnings("unchecked")\r
85                 public <T extends Quantity> Unit<T> getPreferredUnit(Unit<T> u){\r
86                         if ( units.contains(u) )\r
87                                 return u;\r
88                         for( Unit<?> ret : units ){\r
89                                 if ( ret.isCompatible(u) ){\r
90                                         return (Unit<T>) ret;\r
91                                 }\r
92                         }\r
93                         return u;\r
94                 }\r
95                 \r
96                 @SuppressWarnings("unchecked")\r
97                 public <T extends Quantity> Unit<T> getPreferredUnit(Class<T> q){\r
98                         for( Unit<?> u : units ){\r
99                                 try {\r
100                                         return u.asType(q); \r
101                                 } catch ( ClassCastException e ) {\r
102                                         //Not compatible\r
103                                 }\r
104                         }\r
105                         try {\r
106                                 Field f = q.getDeclaredField("UNIT");\r
107                                 if ( Modifier.isStatic(f.getModifiers()) ){\r
108                                         if ( Unit.class.isAssignableFrom(f.getType())){\r
109                                                 return (Unit<T>)f.get(null);\r
110                                         }\r
111                                 }\r
112                         } catch (SecurityException e) {\r
113                                 e.printStackTrace();\r
114                         } catch (NoSuchFieldException e) {\r
115                                 e.printStackTrace();\r
116                         } catch (IllegalArgumentException e) {\r
117                                 // TODO Auto-generated catch block\r
118                                 e.printStackTrace();\r
119                         } catch (IllegalAccessException e) {\r
120                                 // TODO Auto-generated catch block\r
121                                 e.printStackTrace();\r
122                         }\r
123                         return null;\r
124                 }\r
125         }\r
126 \r
127         public static <T extends Quantity> String ammountToString(Amount<T> a) {\r
128                 if ( a == null )\r
129                         return "Null";\r
130                 final NumberFormat nf = new DecimalFormat("##########.###");\r
131                 return nf.format(a.doubleValue(a.getUnit())) + " " + a.getUnit();\r
132         }\r
133         \r
134         public static <T extends Quantity> String ammountToRoundedString(Amount<T> a) {\r
135                 if (a == null)\r
136                         return "Null";\r
137                 Unit<T> u = RocketScience.UnitPreference.preference.getPreferredUnit(a\r
138                                 .getUnit());\r
139                 double d = a.doubleValue(u);\r
140 \r
141                 DecimalFormat df;\r
142 \r
143                 if (Math.abs(d) < 10.0) {\r
144                         df = new DecimalFormat("#.##");\r
145                 } else if (Math.abs(d) < 100.0) {\r
146                         df = new DecimalFormat("#.#");\r
147                 } else {\r
148                         df = new DecimalFormat("#");\r
149                 }\r
150 \r
151                 return df.format(d) + " " + u.toString();\r
152         }\r
153 \r
154 }\r