]> git.gag.com Git - debian/openrocket/blobdiff - core/src/net/sf/openrocket/gui/util/CustomFinImporter.java
create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / gui / util / CustomFinImporter.java
index 09eac8fb4fd7ebbeedcbb2c875b93763d469f536..ae2f7bf422ec0c27aae7f85717f718a32c10443c 100644 (file)
@@ -33,14 +33,21 @@ public class CustomFinImporter {
                startX = -1;
                facing = FacingDirections.UP;
                
-               if (validateImage(pic)) {
-                       points.add(Coordinate.NUL);
-                       loadFin(pic, points);
-               } else {
-                       throw new LocalizedIOException("CustomFinImport.error.badimage");
+               if (!validateImage(pic)) {
+                       throw new LocalizedIOException("CustomFinImport.badFinImage");
                }
-               
-               optimizePoints(points);
+
+               // Load the fin
+               points.add(Coordinate.NUL);
+               loadFin(pic, points);
+
+               // Optimize the loaded fin
+               int count;
+               do {
+                       count = points.size();
+                       optimizePoints(points);
+               } while (count != points.size());
+
                return points;
        }
        
@@ -48,27 +55,27 @@ public class CustomFinImporter {
        private boolean validateImage(BufferedImage pic) {
                int height = pic.getHeight();
                int width = pic.getWidth();
-               Boolean bottomEdgeFound = false;
+               boolean bottomEdgeFound = false;
                
                for (int x = 0; x < width; ++x) {
                        for (int y = 0; y < height; ++y) {
                                int pixel = pic.getRGB(x, y) & 0x00FFFFFF; // Clear alpha, we don't care about it
-                               if ((pixel == 0xFFFFFF) || (pixel == 0)) // black or white only
-                               {
-                                       if ((x == 0) || (x == width - 1) || (y == 0)) {
-                                               // Left, right and top must have no black (fin)
-                                               if (pixel == 0)
-                                                       return false;
-                                       } else if (y == height - 1) {
-                                               if (pixel == 0) {
-                                                       bottomEdgeFound = true;
-                                                       if (startX == -1)
-                                                               startX = x;
-                                               }
+                               // Convert to black & white
+                               int red = (pixel & 0x00FF0000) >> 16;  
+                               int green = (pixel & 0x0000FF00) >> 8;  
+                               int blue = (pixel & 0x000000FF);
+                               pixel =  (int)(0.299*red + 0.587*green + 0.114*blue);
+                               if (pixel > 200)
+                                       pixel = 0xFFFFFF; // White
+                               else
+                                       pixel = 0; // Black
+                               pic.setRGB(x, y, pixel);
+                               if (y == height - 1) {
+                                       if (pixel == 0) {
+                                               bottomEdgeFound = true;
+                                               if (startX == -1)
+                                                       startX = x;
                                        }
-                               } else {
-                                       // Found something other than a black or white pixel
-                                       return false;
                                }
                        }
                }
@@ -76,34 +83,32 @@ public class CustomFinImporter {
        }
        
        private void loadFin(BufferedImage pic, ArrayList<Coordinate> points) {
-               boolean calledTurnedAround = false;
                int height = pic.getHeight();
+               Boolean offBottom = false;
                
                currentX = startX;
-               currentY = pic.getHeight() - 1;
+               currentY = height - 1;
                
                do {
-                       if (CheckLeftIsFin(pic, currentX, currentY))
-                               RotateLeft();
-                       else if (CheckForwardIsFin(pic, currentX, currentY)) {
+                       if (checkLeftIsFin(pic, currentX, currentY))
+                               rotateLeft();
+                       else if (checkForwardIsFin(pic, currentX, currentY)) {
                                // Do nothing
-                       } else if (CheckRightIsFin(pic, currentX, currentY))
-                               RotateRight();
+                       } else if (checkRightIsFin(pic, currentX, currentY))
+                               rotateRight();
                        else {
-                               TurnAround();
-                               calledTurnedAround = true;
+                               turnAround();
                        }
                        
-                       MoveForward(pic);
+                       moveForward(pic);
+                       if (currentY < height - 1)
+                               offBottom = true;
                        if (pixelIsFin(pic, currentX, currentY)) {
-                               if (!calledTurnedAround) {
-                                       double x = (currentX - startX) * 0.001;
-                                       double y = (height - currentY - 1) * 0.001;
-                                       points.add(new Coordinate(x, y));
-                               } else
-                                       calledTurnedAround = false;
+                               double x = (currentX - startX) * 0.001;
+                               double y = (height - currentY - 1) * 0.001;
+                               points.add(new Coordinate(x, y));
                        }
-               } while (currentY < height - 1 && currentY >= 0);
+               } while ((!offBottom) || (currentY < height - 1 && currentY >= 0));
        }
        
        private boolean pixelIsFin(BufferedImage pic, int x, int y) {
@@ -119,7 +124,7 @@ public class CustomFinImporter {
                return false;
        }
        
-       private boolean CheckLeftIsFin(BufferedImage pic, int x, int y) {
+       private boolean checkLeftIsFin(BufferedImage pic, int x, int y) {
                if (facing == FacingDirections.DOWN)
                        return pixelIsFin(pic, x + 1, y);
                else if (facing == FacingDirections.UP)
@@ -132,7 +137,7 @@ public class CustomFinImporter {
                        return false;
        }
        
-       private Boolean CheckRightIsFin(BufferedImage pic, int x, int y) {
+       private boolean checkRightIsFin(BufferedImage pic, int x, int y) {
                if (facing == FacingDirections.DOWN)
                        return pixelIsFin(pic, x - 1, y);
                else if (facing == FacingDirections.UP)
@@ -145,7 +150,7 @@ public class CustomFinImporter {
                        return false;
        }
        
-       private boolean CheckForwardIsFin(BufferedImage pic, int x, int y) {
+       private boolean checkForwardIsFin(BufferedImage pic, int x, int y) {
                if (facing == FacingDirections.DOWN)
                        return pixelIsFin(pic, x, y + 1);
                else if (facing == FacingDirections.UP)
@@ -158,7 +163,7 @@ public class CustomFinImporter {
                        return false;
        }
        
-       private void RotateLeft() {
+       private void rotateLeft() {
                if (facing == FacingDirections.UP)
                        facing = FacingDirections.LEFT;
                else if (facing == FacingDirections.RIGHT)
@@ -169,7 +174,7 @@ public class CustomFinImporter {
                        facing = FacingDirections.DOWN;
        }
        
-       private void RotateRight() {
+       private void rotateRight() {
                if (facing == FacingDirections.UP)
                        facing = FacingDirections.RIGHT;
                else if (facing == FacingDirections.RIGHT)
@@ -180,7 +185,7 @@ public class CustomFinImporter {
                        facing = FacingDirections.UP;
        }
        
-       private void MoveForward(BufferedImage pic) {
+       private void moveForward(BufferedImage pic) {
                if (facing == FacingDirections.UP) {
                        if (currentY > 0)
                                currentY--;
@@ -196,7 +201,7 @@ public class CustomFinImporter {
                }
        }
        
-       private void TurnAround() {
+       private void turnAround() {
                if (facing == FacingDirections.UP)
                        facing = FacingDirections.DOWN;
                else if (facing == FacingDirections.DOWN)
@@ -211,18 +216,20 @@ public class CustomFinImporter {
                int startIx;
                ListIterator<Coordinate> start, entry, entry2;
                Coordinate startPoint, endPoint, testPoint;
+               Boolean removedSection;
                
                startIx = 0;
                start = points.listIterator();
                startPoint = start.next();
                while ((start.hasNext()) && (startPoint != points.get(points.size() - 1))) {
+                       removedSection = false;
                        entry = points.listIterator(points.size());
                        endPoint = entry.previous();
                        for (; endPoint != startPoint; endPoint = entry.previous()) {
                                entry2 = points.listIterator(start.nextIndex());
                                testPoint = entry2.next();
                                for (; testPoint != endPoint; testPoint = entry2.next()) {
-                                       if (pointDistanceFromLine(startPoint, endPoint, testPoint) > 0.001) {
+                                       if (pointDistanceFromLine(startPoint, endPoint, testPoint) > 0.0008) {
                                                break;
                                        }
                                }
@@ -240,10 +247,11 @@ public class CustomFinImporter {
                                        startIx = nextIx;
                                        start = points.listIterator(startIx);
                                        startPoint = start.next();
+                                       removedSection = true;
                                        break;
                                }
                        }
-                       if (endPoint == startPoint) {
+                       if ((!removedSection) && (endPoint == startPoint)) {
                                startIx = start.nextIndex();
                                if (start.hasNext())
                                        startPoint = start.next();