New panels.
[sw/motorsim] / src / com / billkuker / rocketry / motorsim / grain / ExtrudedGrain.java
index 092430048186b41fff1e72b7356775ff3f75a4b7..a60c85dbf1daa21b83604adf2d9bbb1fabe62dc9 100644 (file)
@@ -56,8 +56,6 @@ public class ExtrudedGrain implements Grain, Grain.Graphical {
                Amount<Volume> volume;\r
        }\r
 \r
-       SortedMap<Amount<Length>, RegEntry> data = new TreeMap<Amount<Length>, RegEntry>();\r
-\r
        Amount<Length> webThickness;\r
 \r
        {\r
@@ -71,8 +69,8 @@ public class ExtrudedGrain implements Grain, Grain.Graphical {
                Shape outside = new Ellipse2D.Double(0, 0, 30, 30);\r
                plus.add(outside);\r
                inhibited.add(outside);\r
-               minus.add(new Rectangle2D.Double(12, 25, 5, 10));\r
-               minus.add(new Ellipse2D.Double(10, 4, 5, 5));\r
+               minus.add(new Rectangle2D.Double(13, 13, 4, 30));\r
+               //minus.add(new Ellipse2D.Double(12, 12, 6, 6));\r
                length = Amount.valueOf(70, SI.MILLIMETER);\r
                /**/\r
 \r
@@ -85,89 +83,48 @@ public class ExtrudedGrain implements Grain, Grain.Graphical {
 \r
                findWebThickness();\r
 \r
-               fillInData();\r
        }\r
 \r
        @Override\r
        public Amount<Area> surfaceArea(Amount<Length> regression) {\r
+               Amount<Area> zero = Amount.valueOf(0, Area.UNIT);\r
+               \r
                if (regression.isGreaterThan(webThickness))\r
-                       return Amount.valueOf(0, Area.UNIT);\r
-               Amount<Length> highKey = data.tailMap(regression).firstKey();\r
-               Amount<Length> lowKey;\r
-               try {\r
-                       lowKey = data.headMap(regression).lastKey();\r
-               } catch (NoSuchElementException e) {\r
-                       return data.get(highKey).surfaceArea;\r
-               }\r
-\r
-               double lp = regression.minus(lowKey).divide(highKey.minus(lowKey)).to(\r
-                               Dimensionless.UNIT).doubleValue(Dimensionless.UNIT);\r
+                       return zero;\r
+               \r
+               Amount<Length> rLen = length.minus(regression.times(2));\r
+               if (rLen.isLessThan(Amount.valueOf(0, SI.MILLIMETER)))\r
+                       return zero;\r
 \r
-               Amount<Area> lowVal = data.get(lowKey).surfaceArea;\r
-               Amount<Area> highVal = data.get(highKey).surfaceArea;\r
+               java.awt.geom.Area burn = getCrossSection(regression);\r
+               \r
+               if (burn.isEmpty())\r
+                       return zero;\r
+               \r
+               burn.subtract(getCrossSection(regression.plus(Amount.valueOf(.001,\r
+                               SI.MILLIMETER))));\r
+       \r
+               Amount<Area> xSection = crossSectionArea(regression);\r
 \r
-               return lowVal.times(1 - lp).plus(highVal.times(lp));\r
+               return perimeter(burn).divide(2).times(rLen).plus(\r
+                               xSection.times(2)).to(Area.UNIT);\r
        }\r
 \r
        @Override\r
        public Amount<Volume> volume(Amount<Length> regression) {\r
-               if (regression.isGreaterThan(webThickness))\r
-                       return Amount.valueOf(0, Volume.UNIT);\r
-               Amount<Length> highKey = data.tailMap(regression).firstKey();\r
-               Amount<Length> lowKey;\r
-               try {\r
-                       lowKey = data.headMap(regression).lastKey();\r
-               } catch (NoSuchElementException e) {\r
-                       return data.get(highKey).volume;\r
-               }\r
-\r
-               double lp = regression.minus(lowKey).divide(highKey.minus(lowKey)).to(\r
-                               Dimensionless.UNIT).doubleValue(Dimensionless.UNIT);\r
+               Amount<Volume> zero = Amount.valueOf(0, Volume.UNIT);\r
+               \r
+               Amount<Length> rLen = length.minus(regression.times(2));\r
+               if (rLen.isLessThan(Amount.valueOf(0, SI.MILLIMETER)))\r
+                       return zero;\r
+               \r
+               Amount<Area> xSection = crossSectionArea(regression);\r
 \r
-               Amount<Volume> lowVal = data.get(lowKey).volume;\r
-               Amount<Volume> highVal = data.get(highKey).volume;\r
+               return xSection.times(rLen).to(Volume.UNIT);\r
 \r
-               return lowVal.times(1 - lp).plus(highVal.times(lp));\r
        }\r
 \r
-       private void fillInData() {\r
-               double max = webThickness().doubleValue(SI.MILLIMETER);\r
-               double delta = max / 100;\r
-               rStep = Amount.valueOf(delta, SI.MILLIMETER).divide(10);\r
-               for (double r = 0; r <= max + 1; r += delta) {\r
-                       RegEntry e = new RegEntry();\r
-                       Amount<Length> regression = Amount.valueOf(r, SI.MILLIMETER);\r
 \r
-                       Amount<Length> rLen = length.minus(regression.times(2));\r
-                       if (rLen.isLessThan(Amount.valueOf(0, SI.MILLIMETER)))\r
-                               break;\r
-\r
-                       System.out.println("Calculating area for regression " + regression);\r
-\r
-                       java.awt.geom.Area burn = getArea(regression);\r
-                       if (burn.isEmpty())\r
-                               break;\r
-                       burn.subtract(getArea(regression.plus(Amount.valueOf(.001,\r
-                                       SI.MILLIMETER))));\r
-\r
-                       //Amount<Area> xSection = crossSectionArea(getArea(regression));\r
-                       \r
-                       Amount<Area> xSection = crossSectionArea(regression);\r
-\r
-                       e.volume = xSection.times(rLen).to(Volume.UNIT);\r
-\r
-                       e.surfaceArea = perimeter(burn).divide(2).times(rLen).plus(\r
-                                       xSection.times(2)).to(Area.UNIT);\r
-\r
-                       data.put(regression, e);\r
-\r
-               }\r
-\r
-               RegEntry e = new RegEntry();\r
-               e.surfaceArea = Amount.valueOf(0, Area.UNIT);\r
-               e.volume = Amount.valueOf(0, Volume.UNIT);\r
-               data.put(webThickness(), e);\r
-       }\r
 \r
        \r
        private Amount<Area> crossSectionArea(Amount<Length> regression) {\r
@@ -189,7 +146,7 @@ public class ExtrudedGrain implements Grain, Grain.Graphical {
                \r
                //Subtract PLUS from MINUS and return\r
                Amount<Area> area = plusArea.minus(minusArea);\r
-               System.out.println(area.to(SI.MILLIMETER.pow(2)));\r
+\r
                return area;\r
        }\r
 \r
@@ -227,7 +184,7 @@ public class ExtrudedGrain implements Grain, Grain.Graphical {
        }\r
 \r
        private void findWebThickness() {\r
-               java.awt.geom.Area a = getArea(Amount.valueOf(0, SI.MILLIMETER));\r
+               java.awt.geom.Area a = getCrossSection(Amount.valueOf(0, SI.MILLIMETER));\r
                Rectangle r = a.getBounds();\r
                double max = r.getWidth() < r.getHeight() ? r.getHeight() : r\r
                                .getWidth(); // The max size\r
@@ -237,7 +194,7 @@ public class ExtrudedGrain implements Grain, Grain.Graphical {
                        guess = min + (max - min) / 2; // Guess halfway through\r
                        System.out.println("Min: " + min + " Guess: " + guess + " Max: "\r
                                        + max);\r
-                       a = getArea(Amount.valueOf(guess, SI.MILLIMETER));\r
+                       a = getCrossSection(Amount.valueOf(guess, SI.MILLIMETER));\r
                        if (a.isEmpty()) {\r
                                // guess is too big\r
                                max = guess;\r
@@ -253,12 +210,26 @@ public class ExtrudedGrain implements Grain, Grain.Graphical {
                        webThickness = length.divide(2);\r
        }\r
 \r
-       private java.awt.geom.Area getArea(Amount<Length> regression) {\r
+       @Override\r
+       public java.awt.geom.Area getCrossSection(Amount<Length> regression) {\r
                java.awt.geom.Area res = getPlus(regression);\r
                res.subtract(getMinus(regression));\r
                return res;\r
        }\r
        \r
+       @Override\r
+       public java.awt.geom.Area getSideView(Amount<Length> regression) {\r
+               java.awt.geom.Area res = new java.awt.geom.Area();\r
+               double rLenmm = length.minus(regression.times(2)).doubleValue(SI.MILLIMETER);\r
+               \r
+               for( java.awt.geom.Area a : separate(getCrossSection(regression))){\r
+                       Rectangle2D bounds = a.getBounds2D();\r
+                       Rectangle2D side = new Rectangle2D.Double(bounds.getMinX(), -rLenmm/2.0, bounds.getWidth(), rLenmm);\r
+                       res.add(new java.awt.geom.Area(side));\r
+               }\r
+               return res;\r
+       }\r
+       \r
        private java.awt.geom.Area getPlus(Amount<Length> regression) {\r
                java.awt.geom.Area a = new java.awt.geom.Area();\r
                for (Shape s : plus)\r
@@ -292,15 +263,42 @@ public class ExtrudedGrain implements Grain, Grain.Graphical {
                        return new Ellipse2D.Double(x, y, w, h);\r
                } else if (s instanceof Rectangle2D) {\r
                        Rectangle2D r = (Rectangle2D) s;\r
+                       \r
+                       if ( plus ){\r
+                               double d = -2 * mm;\r
+                               double w = r.getWidth() + d;\r
+                               double h = r.getHeight() + d;\r
+                               double x = r.getX() - d / 2;\r
+                               double y = r.getY() - d / 2;\r
+                               return new Rectangle2D.Double(x, y, w, h);\r
+                       } else {\r
+                               //A rectangular hole gets rounded corners as it grows\r
+                               java.awt.geom.Area a = new java.awt.geom.Area();\r
+                               double d = 2 * mm;\r
+                               \r
+                               //Make it wider\r
+                               double w = r.getWidth() + d;\r
+                               double h = r.getHeight();\r
+                               double x = r.getX() - d / 2;\r
+                               double y = r.getY();\r
+                               a.add( new java.awt.geom.Area(new Rectangle2D.Double(x, y, w, h)));\r
+                               \r
+                               //Make it taller\r
+                               w = r.getWidth();\r
+                               h = r.getHeight() + d;\r
+                               x = r.getX();\r
+                               y = r.getY() - d / 2;\r
+                               a.add( new java.awt.geom.Area(new Rectangle2D.Double(x, y, w, h)));\r
+                               \r
+                               //Add rounded corners\r
+                               a.add( new java.awt.geom.Area(new Ellipse2D.Double(r.getX()-mm, r.getY()-mm, mm*2, mm*2)));\r
+                               a.add( new java.awt.geom.Area(new Ellipse2D.Double(r.getX()+r.getWidth()-mm, r.getY()-mm, mm*2, mm*2)));\r
+                               a.add( new java.awt.geom.Area(new Ellipse2D.Double(r.getX()+r.getWidth()-mm, r.getY()+r.getHeight()-mm, mm*2, mm*2)));\r
+                               a.add( new java.awt.geom.Area(new Ellipse2D.Double(r.getX()-mm, r.getY()+r.getHeight()-mm, mm*2, mm*2)));\r
+                               \r
+                               return a;\r
+                       }\r
 \r
-                       double d = plus ? -2 * mm : 2 * mm;\r
-\r
-                       double w = r.getWidth() + d;\r
-                       double h = r.getHeight() + d;\r
-                       double x = r.getX() - d / 2;\r
-                       double y = r.getY() - d / 2;\r
-\r
-                       return new Rectangle2D.Double(x, y, w, h);\r
                }\r
                return null;\r
        }\r
@@ -310,30 +308,6 @@ public class ExtrudedGrain implements Grain, Grain.Graphical {
                new GrainPanel(e).show();\r
        }\r
 \r
-       @Override\r
-       public void draw(Graphics2D g2d, Amount<Length> regression) {\r
-\r
-               java.awt.geom.Area reg = getArea(regression);\r
-               java.awt.geom.Area burn = getArea(regression);\r
-               burn.subtract(getArea(regression.plus(Amount.valueOf(.001,\r
-                               SI.MILLIMETER))));\r
-               java.awt.geom.Area noreg = getArea(Amount.valueOf(0, SI.MILLIMETER));\r
-\r
-               Rectangle bounds = noreg.getBounds();\r
-               g2d.scale(200 / bounds.getWidth(), 200 / bounds.getHeight());\r
-               g2d.translate(-bounds.getX(), -bounds.getY());\r
-\r
-               g2d.setStroke(new BasicStroke(0.5f));\r
-\r
-               g2d.setColor(Color.GRAY);\r
-               g2d.fill(reg);\r
-               g2d.setColor(Color.RED);\r
-               g2d.draw(burn);\r
-               g2d.setColor(Color.BLACK);\r
-               g2d.draw(noreg);\r
-               \r
-\r
-       }\r
 \r
        /*\r
         * Separate an area into multiple distinct area.\r
@@ -429,7 +403,7 @@ public class ExtrudedGrain implements Grain, Grain.Graphical {
                                y = sy = coords[1];\r
                                break;\r
                        default:\r
-                               System.err.println("Got " + type);\r
+                               throw new Error("Bad segment type from Flattening Path Iterator");\r
                        }\r
                        i.next();\r
                }\r
@@ -439,7 +413,6 @@ public class ExtrudedGrain implements Grain, Grain.Graphical {
                if ( area < 0 ) //Depending on winding it could be negative\r
                        area = area * -1.0;\r
                \r
-               System.out.println(area);\r
                \r
                return Amount.valueOf(area, SI.MILLIMETER.pow(2)).to(Area.UNIT);\r
        }\r