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;
}
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;
}
}
}
}
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) {
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)
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)
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)
return false;
}
- private void RotateLeft() {
+ private void rotateLeft() {
if (facing == FacingDirections.UP)
facing = FacingDirections.LEFT;
else if (facing == FacingDirections.RIGHT)
facing = FacingDirections.DOWN;
}
- private void RotateRight() {
+ private void rotateRight() {
if (facing == FacingDirections.UP)
facing = FacingDirections.RIGHT;
else if (facing == FacingDirections.RIGHT)
facing = FacingDirections.UP;
}
- private void MoveForward(BufferedImage pic) {
+ private void moveForward(BufferedImage pic) {
if (facing == FacingDirections.UP) {
if (currentY > 0)
currentY--;
}
}
- private void TurnAround() {
+ private void turnAround() {
if (facing == FacingDirections.UP)
facing = FacingDirections.DOWN;
else if (facing == FacingDirections.DOWN)
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;
}
}
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();