]> git.gag.com Git - sw/motorsim/commitdiff
Firest checkin of rotated grain
authorBill Kuker <bkuker@billkuker.com>
Tue, 14 Apr 2009 21:01:31 +0000 (21:01 +0000)
committerBill Kuker <bkuker@billkuker.com>
Tue, 14 Apr 2009 21:01:31 +0000 (21:01 +0000)
src/com/billkuker/rocketry/motorsim/grain/RotatedShapeGrain.java [new file with mode: 0644]

diff --git a/src/com/billkuker/rocketry/motorsim/grain/RotatedShapeGrain.java b/src/com/billkuker/rocketry/motorsim/grain/RotatedShapeGrain.java
new file mode 100644 (file)
index 0000000..0c70fe0
--- /dev/null
@@ -0,0 +1,208 @@
+package com.billkuker.rocketry.motorsim.grain;\r
+\r
+import java.awt.Shape;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Area;\r
+import java.awt.geom.Ellipse2D;\r
+import java.awt.geom.GeneralPath;\r
+import java.awt.geom.PathIterator;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import javax.measure.quantity.Length;\r
+import javax.measure.quantity.Volume;\r
+import javax.measure.unit.SI;\r
+\r
+import org.jscience.physics.amount.Amount;\r
+\r
+import com.billkuker.rocketry.motorsim.Grain;\r
+import com.billkuker.rocketry.motorsim.visual.Editor;\r
+import com.billkuker.rocketry.motorsim.visual.GrainPanel;\r
+\r
+public class RotatedShapeGrain implements Grain {\r
+       \r
+       BurningShape shape = new BurningShape();\r
+       \r
+       Amount<Length> web = null;\r
+       \r
+       {\r
+               Shape outside = new Rectangle2D.Double(0,0,15,70);\r
+               shape.add( outside );\r
+               shape.inhibit( outside );\r
+               shape.subtract( new Rectangle2D.Double(0,50,5,70));\r
+               shape.subtract(new Rectangle2D.Double(0, 70, 15, 10));\r
+       }\r
+\r
+       @Override\r
+       public Area getCrossSection(Amount<Length> regression) {\r
+               Area ret = new Area();\r
+               for( Area a : ShapeUtil.separate(shape.getShape(regression))){\r
+                       Rectangle2D b = a.getBounds2D();\r
+                       Ellipse2D inner = new Ellipse2D.Double(-b.getMinX(), -b.getMinX(), b.getMinX()*2, b.getMinX()*2);\r
+                       Ellipse2D outer = new Ellipse2D.Double(-b.getMaxX(), -b.getMaxX(), b.getMaxX()*2, b.getMaxX()*2);\r
+                       Area aa = new Area(outer);\r
+                       aa.subtract(new Area(inner));\r
+                       ret.add(aa);\r
+               }\r
+               return ret;\r
+       }\r
+\r
+       @Override\r
+       public Area getSideView(Amount<Length> regression) {\r
+               Area a = new Area();\r
+               Area reg = shape.getShape(regression);\r
+               a.add(reg);\r
+               a.transform(AffineTransform.getScaleInstance(-1, 1));\r
+               a.add(reg);\r
+               return a;\r
+       }\r
+\r
+       @Override\r
+       public Amount<javax.measure.quantity.Area> surfaceArea(\r
+                       Amount<Length> regression) {\r
+               Amount<javax.measure.quantity.Area> zero = Amount.valueOf(0, javax.measure.quantity.Area.UNIT);\r
+               \r
+               if (regression.isGreaterThan(webThickness()))\r
+                       return zero;\r
+\r
+               java.awt.geom.Area burn = shape.getShape(regression);\r
+               \r
+               if (burn.isEmpty())\r
+                       return zero;\r
+               \r
+               burn.subtract(shape.getShape(regression.plus(Amount.valueOf(.001,\r
+                               SI.MILLIMETER))));\r
+               \r
+               System.out.println(regression);\r
+       \r
+               double sqmm = yRotatedSurfaceArea(burn);\r
+\r
+               \r
+               return Amount.valueOf(sqmm, SI.MILLIMETER.pow(2).asType(javax.measure.quantity.Area.class)).divide(2);\r
+\r
+       }\r
+\r
+       @Override\r
+       public Amount<Volume> volume(Amount<Length> regression) {\r
+               Area squared = new Area(square(shape.getShape(regression)));\r
+               Amount<javax.measure.quantity.Area> sum = Amount.valueOf(0, SI.SQUARE_METRE);\r
+               for( Area a: ShapeUtil.separate(squared) ){\r
+                       sum = sum.plus( ShapeUtil.area(a) );\r
+               }\r
+               Amount<Volume> v = sum.times(Amount.valueOf(Math.PI, SI.MILLIMETER)).to(Volume.UNIT);\r
+               return v;\r
+       }\r
+\r
+       @Override\r
+       public Amount<Length> webThickness() {\r
+               if ( web != null )\r
+                       return web;\r
+               Rectangle2D b = shape.getShape(Amount.valueOf(0, SI.MILLIMETER)).getBounds2D();\r
+               double webmm = b.getWidth()>b.getHeight()?b.getWidth():b.getHeight();\r
+               return web = Amount.valueOf(webmm, SI.MILLIMETER);\r
+       }\r
+       \r
+\r
+       public static void main(String args[]) throws Exception {\r
+               RotatedShapeGrain e = new RotatedShapeGrain();\r
+               new Editor(e).show();\r
+               new GrainPanel(e).show();\r
+       }\r
+       \r
+       private Shape square(java.awt.geom.Area a) {\r
+               PathIterator i = a.getPathIterator(new AffineTransform(), 0.001);\r
+               GeneralPath cur = new GeneralPath();\r
+\r
+               double last[] = {0,0};\r
+               while (!i.isDone()) {\r
+                       double coords[] = new double[6];\r
+                       int type = i.currentSegment(coords);\r
+                       switch (type) {\r
+                       case PathIterator.SEG_CLOSE:\r
+                               cur.closePath();\r
+                               break;\r
+                       case PathIterator.SEG_MOVETO:\r
+                               cur.moveTo(Math.pow(coords[0],2), coords[1]);\r
+                               last[0] = coords[0];\r
+                               last[1] = coords[1];\r
+                               break;\r
+                       case PathIterator.SEG_CUBICTO:\r
+                               throw new Error("Non-flattened geometry!");\r
+                       case PathIterator.SEG_LINETO:\r
+                               double x = last[0];\r
+                               double y = last[1];\r
+                               double len = Math.sqrt(Math.pow(last[0]-coords[0], 2) + Math.pow(last[1]-coords[1], 2));\r
+                               int steps = (int)(len / .01) + 5;\r
+                               for (int s = 0; s < steps; s++) {\r
+                                       x += (coords[0] - last[0]) / steps;\r
+                                       y += (coords[1] - last[1]) / steps;\r
+                                       cur.lineTo(Math.pow(x, 2), y);\r
+                               }\r
+                               last[0] = coords[0];\r
+                               last[1] = coords[1];\r
+                               break;\r
+                       case PathIterator.SEG_QUADTO:\r
+                               throw new Error("Non-flattened geometry!");\r
+\r
+                       }\r
+                       i.next();\r
+               }\r
+               return cur;\r
+       }\r
+       \r
+       private double yRotatedSurfaceArea(java.awt.geom.Area a) {\r
+               PathIterator i = a.getPathIterator(new AffineTransform(), .001);\r
+               double x = 0, y = 0;\r
+               double mx = 0, my = 0;\r
+               double len = 0;\r
+               while (!i.isDone()) {\r
+                       double coords[] = new double[6];\r
+                       int type = i.currentSegment(coords);\r
+                       if (type == PathIterator.SEG_LINETO || type == PathIterator.SEG_CLOSE) {\r
+\r
+\r
+                               double nx = coords[0];\r
+                               double ny = coords[1];\r
+                               \r
+                               if ( type == PathIterator.SEG_CLOSE ){\r
+                                       nx = mx;\r
+                                       ny = my;\r
+                               }\r
+                               \r
+                               double dy = Math.abs(y-ny);\r
+                               double dx = Math.abs(x-nx);\r
+                               double xl = x>nx?x:nx;\r
+                               double xs = x<nx?x:nx;  \r
+                               \r
+                               double add = 0;\r
+                               if ( dx == 0 ){\r
+                                       //Cylender\r
+                                       add = 2 * Math.PI * xl * dy;\r
+                               } else if ( dy == 0 ){\r
+                                       //disk\r
+                                        add = Math.PI * xl * xl - Math.PI * xs * xs;\r
+                               }else{\r
+                                       double h = xl/dx * dy;\r
+                                       double s1 = Math.sqrt(xl*xl + h*h);\r
+                                       double s2 = Math.sqrt(xs*xs + (h-dy)*(h-dy));\r
+                                       add = Math.PI * (xl*s1 - xs*s2);\r
+                               }\r
+                               \r
+                               System.out.println(add);\r
+                               \r
+                               len += add;\r
+\r
+                               x = nx;\r
+                               y = ny;\r
+                       } else if (type == PathIterator.SEG_MOVETO) {\r
+                               mx = x = coords[0];\r
+                               my = y = coords[1];\r
+                       } else {\r
+                               throw new Error("Non-flattened geometry!");\r
+                       }\r
+                       i.next();\r
+               }\r
+               return len;\r
+       }\r
+\r
+\r
+}\r