]> git.gag.com Git - sw/motorsim/blob - src/com/billkuker/rocketry/motorsim/grain/util/ExtrudedShapeGrain.java
Organized grain package
[sw/motorsim] / src / com / billkuker / rocketry / motorsim / grain / util / ExtrudedShapeGrain.java
1 package com.billkuker.rocketry.motorsim.grain.util;\r
2 \r
3 import java.awt.Rectangle;\r
4 import java.awt.Shape;\r
5 import java.awt.geom.Ellipse2D;\r
6 import java.awt.geom.Rectangle2D;\r
7 import java.beans.PropertyVetoException;\r
8 \r
9 import javax.measure.quantity.Area;\r
10 import javax.measure.quantity.Length;\r
11 import javax.measure.quantity.Volume;\r
12 import javax.measure.unit.SI;\r
13 \r
14 import org.jscience.physics.amount.Amount;\r
15 \r
16 import sun.reflect.ReflectionFactory.GetReflectionFactoryAction;\r
17 \r
18 import com.billkuker.rocketry.motorsim.Grain;\r
19 import com.billkuker.rocketry.motorsim.MotorPart;\r
20 import com.billkuker.rocketry.motorsim.grain.ExtrudedGrain;\r
21 import com.billkuker.rocketry.motorsim.visual.Editor;\r
22 import com.billkuker.rocketry.motorsim.visual.GrainPanel;\r
23 \r
24 public abstract class ExtrudedShapeGrain extends ExtrudedGrain {\r
25         \r
26         public static ExtrudedShapeGrain DEFAULT_GRAIN = new ExtrudedShapeGrain(){\r
27                 {\r
28                         try{\r
29                                 Shape outside = new Ellipse2D.Double(0, 0, 30, 30);\r
30                                 xsection.add(outside);\r
31                                 xsection.inhibit(outside);\r
32                                 xsection.subtract(new Ellipse2D.Double(10,10, 10, 10));\r
33                                 setLength(Amount.valueOf(70, SI.MILLIMETER));\r
34                                 setForeEndInhibited(false);\r
35                                 setAftEndInhibited(false);\r
36                         } catch ( Exception e ){\r
37                                 throw new Error(e);\r
38                         }\r
39                 }\r
40         };\r
41 \r
42         protected BurningShape xsection = new BurningShape();\r
43 \r
44         protected Amount<Length> webThickness;\r
45 \r
46         public Amount<Area> surfaceArea(Amount<Length> regression) {\r
47                 Amount<Area> zero = Amount.valueOf(0, Area.UNIT);\r
48                 \r
49                 if (regression.isGreaterThan(webThickness()))\r
50                         return zero;\r
51                 \r
52                 Amount<Length> rLen = regressedLength(regression);\r
53                 \r
54                 if (rLen.isLessThan(Amount.valueOf(0, SI.MILLIMETER)))\r
55                         return zero;\r
56 \r
57                 java.awt.geom.Area burn = getCrossSection(regression);\r
58                 \r
59                 if (burn.isEmpty())\r
60                         return zero;\r
61                 \r
62                 burn.subtract(getCrossSection(regression.plus(Amount.valueOf(.001,\r
63                                 SI.MILLIMETER))));\r
64         \r
65                 Amount<Area> xSection = ShapeUtil.area(xsection.getShape(regression));\r
66                 \r
67                 Amount<Area> sides = ShapeUtil.perimeter(burn).divide(2).times(rLen).to(Area.UNIT);\r
68                 Amount<Area> ends = xSection.times(numberOfBurningEnds(regression));\r
69                 \r
70                 return sides.plus(ends);\r
71 \r
72         }\r
73 \r
74         public Amount<Volume> volume(Amount<Length> regression) {\r
75                 Amount<Volume> zero = Amount.valueOf(0, Volume.UNIT);\r
76                 \r
77                 Amount<Length> rLen = regressedLength(regression);\r
78                 \r
79                 if (rLen.isLessThan(Amount.valueOf(0, SI.MILLIMETER)))\r
80                         return zero;\r
81                 \r
82                 Amount<Area> xSection = ShapeUtil.area(xsection.getShape(regression));\r
83 \r
84                 return xSection.times(rLen).to(Volume.UNIT);\r
85 \r
86         }\r
87 \r
88 \r
89         public Amount<Length> webThickness() {\r
90                 if ( webThickness != null )\r
91                         return webThickness;\r
92                 java.awt.geom.Area a = getCrossSection(Amount.valueOf(0, SI.MILLIMETER));\r
93                 Rectangle r = a.getBounds();\r
94                 double max = r.getWidth() < r.getHeight() ? r.getHeight() : r\r
95                                 .getWidth(); // The max size\r
96                 double min = 0;\r
97                 double guess;\r
98                 while (true) {\r
99                         guess = min + (max - min) / 2; // Guess halfway through\r
100                         System.out.println("Min: " + min + " Guess: " + guess + " Max: "\r
101                                         + max);\r
102                         a = getCrossSection(Amount.valueOf(guess, SI.MILLIMETER));\r
103                         if (a.isEmpty()) {\r
104                                 // guess is too big\r
105                                 max = guess;\r
106                         } else {\r
107                                 // min is too big\r
108                                 min = guess;\r
109                         }\r
110                         if ((max - min) < .01)\r
111                                 break;\r
112                 }\r
113                 webThickness = Amount.valueOf(guess, SI.MILLIMETER);\r
114                 \r
115                 //TODO Need to check # of burning ends!\r
116                 if (webThickness.isGreaterThan(getLength().divide(2)))\r
117                         webThickness = getLength().divide(2);\r
118                 \r
119                 return webThickness;\r
120         }\r
121 \r
122         public java.awt.geom.Area getCrossSection(Amount<Length> regression) {\r
123                 return xsection.getShape(regression);\r
124         }\r
125         \r
126         public java.awt.geom.Area getSideView(Amount<Length> regression) {\r
127                 java.awt.geom.Area res = new java.awt.geom.Area();\r
128                 \r
129                 Amount<Length> rLen = regressedLength(regression);\r
130                 \r
131                 double rLenmm = rLen.doubleValue(SI.MILLIMETER);\r
132                 \r
133                 //TODO Shift up or down based on burning ends\r
134                 for( java.awt.geom.Area a : ShapeUtil.separate(getCrossSection(regression))){\r
135                         Rectangle2D bounds = a.getBounds2D();\r
136                         Rectangle2D side = new Rectangle2D.Double(bounds.getMinX(), -rLenmm/2.0, bounds.getWidth(), rLenmm);\r
137                         res.add(new java.awt.geom.Area(side));\r
138                 }\r
139                 return res;\r
140         }\r
141         \r
142         public static void main(String args[]) throws Exception {\r
143                 ExtrudedShapeGrain e = DEFAULT_GRAIN;\r
144                 new Editor(e).showAsWindow();\r
145                 new GrainPanel(e).showAsWindow();\r
146         }\r
147 \r
148 }\r