]> git.gag.com Git - sw/motorsim/blob - src/com/billkuker/rocketry/motorsim/grain/BurningShape.java
c31a9eea98bafa346b0333e4b1c50d3959aca183
[sw/motorsim] / src / com / billkuker / rocketry / motorsim / grain / BurningShape.java
1 package com.billkuker.rocketry.motorsim.grain;\r
2 \r
3 import java.awt.Shape;\r
4 import java.awt.geom.Area;\r
5 import java.awt.geom.Ellipse2D;\r
6 import java.awt.geom.Rectangle2D;\r
7 import java.awt.geom.RoundRectangle2D;\r
8 import java.util.HashSet;\r
9 import java.util.Set;\r
10 \r
11 import javax.measure.quantity.Length;\r
12 import javax.measure.unit.SI;\r
13 \r
14 import org.jscience.physics.amount.Amount;\r
15 \r
16 public class BurningShape {\r
17         Set<Shape> plus = new HashSet<Shape>();\r
18         Set<Shape> minus = new HashSet<Shape>();\r
19         Set<Shape> inhibited = new HashSet<Shape>();\r
20         \r
21         public void add(Shape s){\r
22                 plus.add(s);\r
23         }\r
24         \r
25         public void subtract(Shape s){\r
26                 minus.add(s);\r
27         }\r
28         \r
29         public void inhibit(Shape s){\r
30                 inhibited.add(s);\r
31         }\r
32 \r
33         /*\r
34          * 9 times out of 10 we get asked for the same thing\r
35          * 2x in a row, for volume and for area\r
36          */\r
37         private Amount<Length> lastRegression = null;\r
38         private Area lastArea = null;\r
39         \r
40         public java.awt.geom.Area getShape(Amount<Length> regression) {\r
41                 if ( regression.equals(lastRegression) ){\r
42                         return lastArea;\r
43                 }\r
44                 lastRegression = regression;\r
45 \r
46                 java.awt.geom.Area a = new java.awt.geom.Area();\r
47                 for (Shape s : plus)\r
48                         a.add(new java.awt.geom.Area(regress(s, regression\r
49                                         .doubleValue(SI.MILLIMETER), true)));\r
50                 for (Shape s : minus)\r
51                         a.subtract(new java.awt.geom.Area(regress(s, regression\r
52                                         .doubleValue(SI.MILLIMETER), false)));\r
53                 \r
54                 return lastArea = a;\r
55         }\r
56         \r
57         private Shape regress(Shape s, double mm, boolean plus) {\r
58                 if (inhibited.contains(s))\r
59                         return s;\r
60                 if (s instanceof Ellipse2D) {\r
61                         Ellipse2D e = (Ellipse2D) s;\r
62 \r
63                         double d = plus ? -2 * mm : 2 * mm;\r
64 \r
65                         double w = e.getWidth() + d;\r
66                         double h = e.getHeight() + d;\r
67                         double x = e.getX() - d / 2;\r
68                         double y = e.getY() - d / 2;\r
69 \r
70                         return new Ellipse2D.Double(x, y, w, h);\r
71                 } else if (s instanceof Rectangle2D) {\r
72                         Rectangle2D r = (Rectangle2D) s;\r
73                         \r
74                         if ( plus ){\r
75                                 double d = -2 * mm;\r
76                                 double w = r.getWidth() + d;\r
77                                 double h = r.getHeight() + d;\r
78                                 double x = r.getX() - d / 2;\r
79                                 double y = r.getY() - d / 2;\r
80                                 return new Rectangle2D.Double(x, y, w, h);\r
81                         } else {\r
82                                 //A rectangular hole gets rounded corners as it grows\r
83                                 java.awt.geom.Area a = new java.awt.geom.Area();\r
84                                 double d = 2 * mm;\r
85                                 \r
86                                 a.add(new Area(new RoundRectangle2D.Double(\r
87                                                 r.getX() - d / 2,\r
88                                                 r.getY() - d / 2,\r
89                                                 r.getWidth() + d,\r
90                                                 r.getHeight() + d,\r
91                                                 d,\r
92                                                 d\r
93                                                 )));\r
94 \r
95                                 return a;\r
96                         }\r
97 \r
98                 }\r
99                 return null;\r
100         }\r
101 \r
102         \r
103 }\r