Separated out birning shape so that I might use it for the rotated grain
authorBill Kuker <bkuker@billkuker.com>
Tue, 14 Apr 2009 19:05:57 +0000 (19:05 +0000)
committerBill Kuker <bkuker@billkuker.com>
Tue, 14 Apr 2009 19:05:57 +0000 (19:05 +0000)
src/com/billkuker/rocketry/motorsim/grain/BurningShape.java [new file with mode: 0644]
src/com/billkuker/rocketry/motorsim/grain/ExtrudedShapeGrain.java
src/com/billkuker/rocketry/motorsim/grain/ShapeUtil.java [new file with mode: 0644]

diff --git a/src/com/billkuker/rocketry/motorsim/grain/BurningShape.java b/src/com/billkuker/rocketry/motorsim/grain/BurningShape.java
new file mode 100644 (file)
index 0000000..31d9b0f
--- /dev/null
@@ -0,0 +1,111 @@
+package com.billkuker.rocketry.motorsim.grain;\r
+\r
+import java.awt.Shape;\r
+import java.awt.geom.Ellipse2D;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import javax.measure.quantity.Length;\r
+import javax.measure.unit.SI;\r
+\r
+import org.jscience.physics.amount.Amount;\r
+\r
+public class BurningShape {\r
+       Set<Shape> plus = new HashSet<Shape>();\r
+       Set<Shape> minus = new HashSet<Shape>();\r
+       Set<Shape> inhibited = new HashSet<Shape>();\r
+       \r
+       public void add(Shape s){\r
+               plus.add(s);\r
+       }\r
+       \r
+       public void subtract(Shape s){\r
+               minus.add(s);\r
+       }\r
+       \r
+       public void inhibit(Shape s){\r
+               inhibited.add(s);\r
+       }\r
+\r
+       public java.awt.geom.Area getShape(Amount<Length> regression) {\r
+               java.awt.geom.Area res = getPlus(regression);\r
+               res.subtract(getMinus(regression));\r
+               return res;\r
+       }\r
+       \r
+       \r
+       public 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
+                       a.add(new java.awt.geom.Area(regress(s, regression\r
+                                       .doubleValue(SI.MILLIMETER), true)));\r
+               return a;\r
+       }\r
+       \r
+       public java.awt.geom.Area getMinus(Amount<Length> regression) {\r
+               java.awt.geom.Area a = new java.awt.geom.Area();\r
+               for (Shape s : minus)\r
+                       a.add(new java.awt.geom.Area(regress(s, regression\r
+                                       .doubleValue(SI.MILLIMETER), false)));\r
+               return a;\r
+       }\r
+       \r
+       private Shape regress(Shape s, double mm, boolean plus) {\r
+               if (inhibited.contains(s))\r
+                       return s;\r
+               if (s instanceof Ellipse2D) {\r
+                       Ellipse2D e = (Ellipse2D) s;\r
+\r
+                       double d = plus ? -2 * mm : 2 * mm;\r
+\r
+                       double w = e.getWidth() + d;\r
+                       double h = e.getHeight() + d;\r
+                       double x = e.getX() - d / 2;\r
+                       double y = e.getY() - d / 2;\r
+\r
+                       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
+               }\r
+               return null;\r
+       }\r
+\r
+       \r
+}\r
index e9557ebf67b5ebcb3ede714acca7803db6b7a126..1a8851e890e7b687aa71ddf3f9aec0633781a63f 100644 (file)
@@ -25,11 +25,7 @@ import com.billkuker.rocketry.motorsim.visual.GrainPanel;
 \r
 public class ExtrudedShapeGrain extends MotorPart implements Grain {\r
 \r
-       Set<Shape> plus = new HashSet<Shape>();\r
-\r
-       Set<Shape> minus = new HashSet<Shape>();\r
-\r
-       Set<Shape> inhibited = new HashSet<Shape>();\r
+       BurningShape xsection = new BurningShape();\r
 \r
        Amount<Length> length = Amount.valueOf(25, SI.MILLIMETER);\r
        \r
@@ -48,9 +44,9 @@ public class ExtrudedShapeGrain extends MotorPart implements Grain {
 \r
                /* Big c-slot */\r
                Shape outside = new Ellipse2D.Double(0, 0, 30, 30);\r
-               plus.add(outside);\r
-               inhibited.add(outside);\r
-               minus.add(new Rectangle2D.Double(13, 13, 4, 30));\r
+               xsection.add(outside);\r
+               xsection.inhibit(outside);\r
+               xsection.subtract(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
@@ -90,7 +86,7 @@ public class ExtrudedShapeGrain extends MotorPart implements Grain {
        \r
                Amount<Area> xSection = crossSectionArea(regression);\r
 \r
-               return perimeter(burn).divide(2).times(rLen).plus(\r
+               return ShapeUtil.perimeter(burn).divide(2).times(rLen).plus(\r
                                xSection.times(2)).to(Area.UNIT);\r
        }\r
 \r
@@ -116,19 +112,19 @@ public class ExtrudedShapeGrain extends MotorPart implements Grain {
        \r
        private Amount<Area> crossSectionArea(Amount<Length> regression) {\r
                //Get the PLUS shape and sum its area\r
-               java.awt.geom.Area plus = getPlus(regression);\r
+               java.awt.geom.Area plus = xsection.getPlus(regression);\r
                Amount<Area> plusArea = Amount.valueOf(0, SI.SQUARE_METRE);\r
-               for (java.awt.geom.Area a : separate(plus)) {\r
-                       plusArea = plusArea.plus(area(a));\r
+               for (java.awt.geom.Area a : ShapeUtil.separate(plus)) {\r
+                       plusArea = plusArea.plus(ShapeUtil.area(a));\r
                }\r
                \r
                //Get the MINUS shape, intersect it with PLUS to get just the parts\r
                //that are removed, sum it's area\r
-               java.awt.geom.Area minus = getMinus(regression);\r
+               java.awt.geom.Area minus = xsection.getMinus(regression);\r
                minus.intersect(plus);\r
                Amount<Area> minusArea = Amount.valueOf(0, SI.SQUARE_METRE);\r
-               for (java.awt.geom.Area a : separate(minus)) {\r
-                       minusArea = minusArea.plus(area(a));\r
+               for (java.awt.geom.Area a : ShapeUtil.separate(minus)) {\r
+                       minusArea = minusArea.plus(ShapeUtil.area(a));\r
                }\r
                \r
                //Subtract PLUS from MINUS and return\r
@@ -142,34 +138,6 @@ public class ExtrudedShapeGrain extends MotorPart implements Grain {
                return webThickness;\r
        }\r
 \r
-       private Amount<Length> perimeter(java.awt.geom.Area a) {\r
-               //TODO: I think I need to handle seg_close!!\r
-               PathIterator i = a.getPathIterator(new AffineTransform(), .001);\r
-               double x = 0, y = 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) {\r
-                               // System.out.println("Line");\r
-                               double nx = coords[0];\r
-                               double ny = coords[1];\r
-                               // System.out.println(x+","+y+ " to " + nx+"," + ny);\r
-                               len += Math.sqrt(Math.pow(x - nx, 2) + Math.pow(y - ny, 2));\r
-                               x = nx;\r
-                               y = ny;\r
-                       } else if (type == PathIterator.SEG_MOVETO) {\r
-                               // System.out.println("Move");\r
-                               x = coords[0];\r
-                               y = coords[1];\r
-                       } else {\r
-                               // System.err.println("Got " + type);\r
-                       }\r
-                       i.next();\r
-               }\r
-               return Amount.valueOf(len, SI.MILLIMETER);\r
-       }\r
-\r
        private void findWebThickness() {\r
                java.awt.geom.Area a = getCrossSection(Amount.valueOf(0, SI.MILLIMETER));\r
                Rectangle r = a.getBounds();\r
@@ -199,9 +167,7 @@ public class ExtrudedShapeGrain extends MotorPart implements Grain {
 \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
+               return xsection.getShape(regression);\r
        }\r
        \r
        @Override\r
@@ -214,7 +180,7 @@ public class ExtrudedShapeGrain extends MotorPart implements Grain {
                \r
                double rLenmm = rLen.doubleValue(SI.MILLIMETER);\r
                \r
-               for( java.awt.geom.Area a : separate(getCrossSection(regression))){\r
+               for( java.awt.geom.Area a : ShapeUtil.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
@@ -222,79 +188,6 @@ public class ExtrudedShapeGrain extends MotorPart implements Grain {
                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
-                       a.add(new java.awt.geom.Area(regress(s, regression\r
-                                       .doubleValue(SI.MILLIMETER), true)));\r
-               return a;\r
-       }\r
-       \r
-       private java.awt.geom.Area getMinus(Amount<Length> regression) {\r
-               java.awt.geom.Area a = new java.awt.geom.Area();\r
-               for (Shape s : minus)\r
-                       a.add(new java.awt.geom.Area(regress(s, regression\r
-                                       .doubleValue(SI.MILLIMETER), false)));\r
-               return a;\r
-       }\r
-       \r
-\r
-       private Shape regress(Shape s, double mm, boolean plus) {\r
-               if (inhibited.contains(s))\r
-                       return s;\r
-               if (s instanceof Ellipse2D) {\r
-                       Ellipse2D e = (Ellipse2D) s;\r
-\r
-                       double d = plus ? -2 * mm : 2 * mm;\r
-\r
-                       double w = e.getWidth() + d;\r
-                       double h = e.getHeight() + d;\r
-                       double x = e.getX() - d / 2;\r
-                       double y = e.getY() - d / 2;\r
-\r
-                       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
-               }\r
-               return null;\r
-       }\r
-\r
        public static void main(String args[]) throws Exception {\r
                ExtrudedShapeGrain e = new ExtrudedShapeGrain();\r
                new Editor(e).show();\r
@@ -302,114 +195,6 @@ public class ExtrudedShapeGrain extends MotorPart implements Grain {
        }\r
 \r
 \r
-       /*\r
-        * Separate an area into multiple distinct area.\r
-        * Area CAN NOT HAVE HOLES. HOLES WILL BE RETURNED AS AREAS,\r
-        * SO A DONUT WILL TURN INTO TWO CIRCLES.\r
-        */\r
-       private Set<java.awt.geom.Area> separate(java.awt.geom.Area a) {\r
-               Set<java.awt.geom.Area> res = new HashSet<java.awt.geom.Area>();\r
-               PathIterator i = a.getPathIterator(new AffineTransform());\r
-               GeneralPath cur = null;\r
-\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
-                               if (cur != null ){\r
-                                       java.awt.geom.Area area = new java.awt.geom.Area(cur);\r
-                                       if ( !a.isEmpty() )\r
-                                               res.add(area);\r
-                               }\r
-                               cur = new GeneralPath(i.getWindingRule());\r
-                               break;\r
-                       case PathIterator.SEG_MOVETO:\r
-                               if (cur != null ){\r
-                                       java.awt.geom.Area area = new java.awt.geom.Area(cur);\r
-                                       if ( !a.isEmpty() )\r
-                                               res.add(area);\r
-                               }\r
-                               cur = new GeneralPath(i.getWindingRule());\r
-                               cur.moveTo(coords[0], coords[1]);\r
-                               break;\r
-                       case PathIterator.SEG_CUBICTO:\r
-                               cur.curveTo(coords[0], coords[1], coords[2], coords[3],\r
-                                               coords[4], coords[5]);\r
-                               break;\r
-                       case PathIterator.SEG_LINETO:\r
-                               cur.lineTo(coords[0], coords[1]);\r
-                               break;\r
-                       case PathIterator.SEG_QUADTO:\r
-                               cur.quadTo(coords[0], coords[1], coords[2], coords[3]);\r
-                               break;\r
-\r
-                       }\r
-                       i.next();\r
-               }\r
-\r
-               return res;\r
-       }\r
-       \r
-       /*\r
-        * Return the Area of a singular polygon (NO HOLES OR DISJOINT PARTS).\r
-        * Coordinates assumed to be in MM.\r
-        * http://valis.cs.uiuc.edu/~sariel/research/CG/compgeom/msg00831.html\r
-        * http://stackoverflow.com/questions/451426/how-do-i-calculate-the-surface-area-of-a-2d-polygon\r
-        * http://www.wikihow.com/Calculate-the-Area-of-a-Polygon\r
-        */\r
-       private Amount<Area> area(java.awt.geom.Area a) {\r
-               if ( !a.isSingular() )\r
-                       throw new IllegalArgumentException("Can not calculate area of non-singular shape!");\r
-               PathIterator i = a.getPathIterator(new AffineTransform(), .001);\r
-               \r
-               \r
-               double x = 0, y = 0, sx = 0, sy = 0;\r
-               double nx, ny;\r
-               double area = 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
-                               //Go back to the start\r
-                               nx = sx;\r
-                               ny = sy;\r
-                               area += x * ny;\r
-                               area -= y * nx;\r
-                               break;\r
-                       case PathIterator.SEG_LINETO:\r
-                               nx = coords[0];\r
-                               ny = coords[1];\r
-                               area += x * ny;\r
-                               area -= y * nx;\r
-\r
-                               //Remember the last points\r
-                               x = nx;\r
-                               y = ny;\r
-                               \r
-                               break;\r
-                       case PathIterator.SEG_MOVETO:\r
-                               //Remember the starting point\r
-                               x = sx = coords[0];\r
-                               y = sy = coords[1];\r
-                               break;\r
-                       default:\r
-                               throw new Error("Bad segment type from Flattening Path Iterator");\r
-                       }\r
-                       i.next();\r
-               }\r
-               \r
-               area = area / 2.0; // Result so far is double the signed area\r
-               \r
-               if ( area < 0 ) //Depending on winding it could be negative\r
-                       area = area * -1.0;\r
-               \r
-               \r
-               return Amount.valueOf(area, SI.MILLIMETER.pow(2)).to(Area.UNIT);\r
-       }\r
-\r
        public Amount<Length> getLength() {\r
                return length;\r
        }\r
diff --git a/src/com/billkuker/rocketry/motorsim/grain/ShapeUtil.java b/src/com/billkuker/rocketry/motorsim/grain/ShapeUtil.java
new file mode 100644 (file)
index 0000000..23e8e2d
--- /dev/null
@@ -0,0 +1,153 @@
+package com.billkuker.rocketry.motorsim.grain;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.GeneralPath;\r
+import java.awt.geom.PathIterator;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import javax.measure.quantity.Area;\r
+import javax.measure.quantity.Length;\r
+import javax.measure.unit.SI;\r
+\r
+import org.jscience.physics.amount.Amount;\r
+public class ShapeUtil {\r
+       private ShapeUtil(){}\r
+\r
+       /*\r
+        * Return the Area of a singular polygon (NO HOLES OR DISJOINT PARTS).\r
+        * Coordinates assumed to be in MM.\r
+        * http://valis.cs.uiuc.edu/~sariel/research/CG/compgeom/msg00831.html\r
+        * http://stackoverflow.com/questions/451426/how-do-i-calculate-the-surface-area-of-a-2d-polygon\r
+        * http://www.wikihow.com/Calculate-the-Area-of-a-Polygon\r
+        */\r
+       public static Amount<Area> area(java.awt.geom.Area a) {\r
+               if ( !a.isSingular() )\r
+                       throw new IllegalArgumentException("Can not calculate area of non-singular shape!");\r
+               PathIterator i = a.getPathIterator(new AffineTransform(), .001);\r
+               \r
+               \r
+               double x = 0, y = 0, sx = 0, sy = 0;\r
+               double nx, ny;\r
+               double area = 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
+                               //Go back to the start\r
+                               nx = sx;\r
+                               ny = sy;\r
+                               area += x * ny;\r
+                               area -= y * nx;\r
+                               break;\r
+                       case PathIterator.SEG_LINETO:\r
+                               nx = coords[0];\r
+                               ny = coords[1];\r
+                               area += x * ny;\r
+                               area -= y * nx;\r
+       \r
+                               //Remember the last points\r
+                               x = nx;\r
+                               y = ny;\r
+                               \r
+                               break;\r
+                       case PathIterator.SEG_MOVETO:\r
+                               //Remember the starting point\r
+                               x = sx = coords[0];\r
+                               y = sy = coords[1];\r
+                               break;\r
+                       default:\r
+                               throw new Error("Bad segment type from Flattening Path Iterator");\r
+                       }\r
+                       i.next();\r
+               }\r
+               \r
+               area = area / 2.0; // Result so far is double the signed area\r
+               \r
+               if ( area < 0 ) //Depending on winding it could be negative\r
+                       area = area * -1.0;\r
+               \r
+               \r
+               return Amount.valueOf(area, SI.MILLIMETER.pow(2)).to(Area.UNIT);\r
+       }\r
+\r
+       public static Amount<Length> perimeter(java.awt.geom.Area a) {\r
+               //TODO: I think I need to handle seg_close!!\r
+               PathIterator i = a.getPathIterator(new AffineTransform(), .001);\r
+               double x = 0, y = 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) {\r
+                               // System.out.println("Line");\r
+                               double nx = coords[0];\r
+                               double ny = coords[1];\r
+                               // System.out.println(x+","+y+ " to " + nx+"," + ny);\r
+                               len += Math.sqrt(Math.pow(x - nx, 2) + Math.pow(y - ny, 2));\r
+                               x = nx;\r
+                               y = ny;\r
+                       } else if (type == PathIterator.SEG_MOVETO) {\r
+                               // System.out.println("Move");\r
+                               x = coords[0];\r
+                               y = coords[1];\r
+                       } else {\r
+                               // System.err.println("Got " + type);\r
+                       }\r
+                       i.next();\r
+               }\r
+               return Amount.valueOf(len, SI.MILLIMETER);\r
+       }\r
+\r
+       /*\r
+        * Separate an area into multiple distinct area.\r
+        * Area CAN NOT HAVE HOLES. HOLES WILL BE RETURNED AS AREAS,\r
+        * SO A DONUT WILL TURN INTO TWO CIRCLES.\r
+        */\r
+       public static Set<java.awt.geom.Area> separate(java.awt.geom.Area a) {\r
+               Set<java.awt.geom.Area> res = new HashSet<java.awt.geom.Area>();\r
+               PathIterator i = a.getPathIterator(new AffineTransform());\r
+               GeneralPath cur = null;\r
+       \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
+                               if (cur != null ){\r
+                                       java.awt.geom.Area area = new java.awt.geom.Area(cur);\r
+                                       if ( !a.isEmpty() )\r
+                                               res.add(area);\r
+                               }\r
+                               cur = new GeneralPath(i.getWindingRule());\r
+                               break;\r
+                       case PathIterator.SEG_MOVETO:\r
+                               if (cur != null ){\r
+                                       java.awt.geom.Area area = new java.awt.geom.Area(cur);\r
+                                       if ( !a.isEmpty() )\r
+                                               res.add(area);\r
+                               }\r
+                               cur = new GeneralPath(i.getWindingRule());\r
+                               cur.moveTo(coords[0], coords[1]);\r
+                               break;\r
+                       case PathIterator.SEG_CUBICTO:\r
+                               cur.curveTo(coords[0], coords[1], coords[2], coords[3],\r
+                                               coords[4], coords[5]);\r
+                               break;\r
+                       case PathIterator.SEG_LINETO:\r
+                               cur.lineTo(coords[0], coords[1]);\r
+                               break;\r
+                       case PathIterator.SEG_QUADTO:\r
+                               cur.quadTo(coords[0], coords[1], coords[2], coords[3]);\r
+                               break;\r
+       \r
+                       }\r
+                       i.next();\r
+               }\r
+       \r
+               return res;\r
+       }\r
+       \r
+       \r
+}\r