Fixed some warnings
[sw/motorsim] / src / com / billkuker / rocketry / motorsim / GraphSimplifier.java
1 package com.billkuker.rocketry.motorsim;
2
3 import java.lang.reflect.InvocationTargetException;
4 import java.lang.reflect.Method;
5 import java.util.Collections;
6 import java.util.HashMap;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.SortedMap;
11 import java.util.TreeMap;
12 import java.util.Vector;
13
14 import javax.measure.quantity.Area;
15 import javax.measure.quantity.Length;
16 import javax.measure.quantity.Quantity;
17 import javax.measure.unit.SI;
18
19 import org.jscience.physics.amount.Amount;
20
21 import com.billkuker.rocketry.motorsim.grain.CoredCylindricalGrain;
22 import com.billkuker.rocketry.motorsim.visual.Chart;
23
24 public class GraphSimplifier<X extends Quantity, Y extends Quantity> {
25         Method f;
26
27         private class Entry {
28                 Amount<X> x;
29                 Amount<Y> y;
30         }
31
32         private class DDEntry implements Comparable<DDEntry> {
33                 Amount<X> x;
34                 Amount dd;
35
36                 @Override
37                 public int compareTo(DDEntry o) {
38                         return dd.compareTo(o.dd);
39                 }
40         }
41
42         private SortedMap<Amount<X>, Amount<Y>> out = new TreeMap<Amount<X>, Amount<Y>>();
43
44         public Amount<Y> value(Amount<X> x) {
45                 return out.get(x);
46         }
47
48         public Iterable<Amount<X>> getDomain() {
49                 return out.keySet();
50         }
51
52         public GraphSimplifier(Object source, String method,
53                         Iterator<Amount<X>> domain) throws NoSuchMethodException,
54                         IllegalArgumentException, IllegalAccessException,
55                         InvocationTargetException {
56                 f = source.getClass().getMethod(method, Amount.class);
57
58                 Vector<Entry> oldEntries = new Vector<Entry>();
59
60                 while (domain.hasNext()) {
61                         Amount<X> x = domain.next();
62                         Amount<Y> y = (Amount<Y>) f.invoke(source, x);
63                         Entry e = new Entry();
64                         e.x = x;
65                         e.y = y;
66                         oldEntries.add(e);
67                 }
68
69                 List<DDEntry> byDD = new Vector<DDEntry>();
70                 Map<Amount<X>, Amount<Y>> byX = new HashMap<Amount<X>, Amount<Y>>();
71
72                 for (int i = 1; i < oldEntries.size() - 1; i++) {
73                         Entry low = oldEntries.elementAt(i - 1);
74                         Entry middle = oldEntries.elementAt(i);
75                         Entry high = oldEntries.elementAt(i + 1);
76
77                         Amount<?> d1, d2, dd;
78
79                         d1 = middle.y.minus(low.y).divide(middle.x.minus(low.x));
80                         d2 = high.y.minus(middle.y).divide(high.x.minus(middle.x));
81                         dd = d2.minus(d1).divide(high.x.minus(low.x));
82
83                         DDEntry dde = new DDEntry();
84                         dde.dd = dd.abs();
85                         dde.x = middle.x;
86
87                         byDD.add(dde);
88                         byX.put(middle.x, middle.y);
89
90                 }
91
92                 Collections.sort(byDD);
93
94                 out.put(oldEntries.elementAt(0).x, oldEntries.elementAt(0).y);
95                 int count = 0;
96                 for (DDEntry dde : byDD) {
97                         out.put(dde.x, byX.get(dde.x));
98                         if (++count >= 20)
99                                 break;
100                 }
101                 int last = oldEntries.size() - 1;
102                 out.put(oldEntries.elementAt(last).x, oldEntries.elementAt(last).y);
103
104         }
105
106         public static void main(String args[]) throws Exception {
107                 CoredCylindricalGrain g = new CoredCylindricalGrain();
108                 g.setLength(Amount.valueOf(70, SI.MILLIMETER));
109                 g.setOD(Amount.valueOf(30, SI.MILLIMETER));
110                 g.setID(Amount.valueOf(10, SI.MILLIMETER));
111
112                 Chart<Length, Area> c = new Chart<Length, Area>(SI.MILLIMETER,
113                                 SI.MILLIMETER.pow(2).asType(Area.class), g, "surfaceArea");
114                 c.setDomain(c.new IntervalDomain(Amount.valueOf(0, SI.CENTIMETER), g
115                                 .webThickness()));
116                 c.show();
117
118                 GraphSimplifier<Length, Area> gs = new GraphSimplifier(g,
119                                 "surfaceArea", c.new IntervalDomain(Amount.valueOf(0,
120                                                 SI.CENTIMETER), g.webThickness()).iterator());
121
122                 Chart<Length, Area> d = new Chart<Length, Area>(SI.MILLIMETER,
123                                 SI.MILLIMETER.pow(2).asType(Area.class), gs, "value");
124                 d.setDomain(gs.getDomain());
125                 d.show();
126         }
127 }