1 package com.billkuker.rocketry.motorsim;
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;
10 import java.util.SortedMap;
11 import java.util.TreeMap;
12 import java.util.Vector;
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 import javax.swing.JFrame;
19 import javax.swing.JSplitPane;
21 import org.jscience.physics.amount.Amount;
23 import com.billkuker.rocketry.motorsim.grain.CoredCylindricalGrain;
24 import com.billkuker.rocketry.motorsim.visual.Chart;
26 public class GraphSimplifier<X extends Quantity, Y extends Quantity> {
34 private class DDEntry implements Comparable<DDEntry> {
39 public int compareTo(DDEntry o) {
40 return dd.compareTo(o.dd);
44 private SortedMap<Amount<X>, Amount<Y>> out = new TreeMap<Amount<X>, Amount<Y>>();
46 public Amount<Y> value(Amount<X> x) {
50 public Iterable<Amount<X>> getDomain() {
54 public GraphSimplifier(Object source, String method,
55 Iterator<Amount<X>> domain) throws NoSuchMethodException,
56 IllegalArgumentException, IllegalAccessException,
57 InvocationTargetException {
58 f = source.getClass().getMethod(method, Amount.class);
60 Vector<Entry> oldEntries = new Vector<Entry>();
62 while (domain.hasNext()) {
63 Amount<X> x = domain.next();
64 Amount<Y> y = (Amount<Y>) f.invoke(source, x);
65 Entry e = new Entry();
71 List<DDEntry> byDD = new Vector<DDEntry>();
72 Map<Amount<X>, Amount<Y>> byX = new HashMap<Amount<X>, Amount<Y>>();
74 for (int i = 1; i < oldEntries.size() - 1; i++) {
75 Entry low = oldEntries.elementAt(i - 1);
76 Entry middle = oldEntries.elementAt(i);
77 Entry high = oldEntries.elementAt(i + 1);
81 d1 = middle.y.minus(low.y).divide(middle.x.minus(low.x));
82 d2 = high.y.minus(middle.y).divide(high.x.minus(middle.x));
83 dd = d2.minus(d1).divide(high.x.minus(low.x));
85 DDEntry dde = new DDEntry();
90 byX.put(middle.x, middle.y);
94 Collections.sort(byDD);
96 out.put(oldEntries.elementAt(0).x, oldEntries.elementAt(0).y);
98 for (DDEntry dde : byDD) {
99 out.put(dde.x, byX.get(dde.x));
103 int last = oldEntries.size() - 1;
104 out.put(oldEntries.elementAt(last).x, oldEntries.elementAt(last).y);
108 public static void main(String args[]) throws Exception {
109 CoredCylindricalGrain g = new CoredCylindricalGrain();
110 g.setLength(Amount.valueOf(70, SI.MILLIMETER));
111 g.setOD(Amount.valueOf(30, SI.MILLIMETER));
112 g.setID(Amount.valueOf(10, SI.MILLIMETER));
114 JFrame f = new JFrame();
115 f.setSize(1024, 768);
116 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
117 JSplitPane jsp = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
120 Chart<Length, Area> c = new Chart<Length, Area>(SI.MILLIMETER,
121 SI.MILLIMETER.pow(2).asType(Area.class), g, "surfaceArea");
122 c.setDomain(c.new IntervalDomain(Amount.valueOf(0, SI.CENTIMETER), g
124 jsp.setTopComponent(c);
126 GraphSimplifier<Length, Area> gs = new GraphSimplifier(g,
127 "surfaceArea", c.new IntervalDomain(Amount.valueOf(0,
128 SI.CENTIMETER), g.webThickness()).iterator());
130 Chart<Length, Area> d = new Chart<Length, Area>(SI.MILLIMETER,
131 SI.MILLIMETER.pow(2).asType(Area.class), gs, "value");
132 d.setDomain(gs.getDomain());
133 jsp.setBottomComponent(d);
136 jsp.setDividerLocation(.5);