/* * Copyright (c) 2009, 2010, 2011 Daniel Rendall * This file is part of FractDim. * * FractDim is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FractDim is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FractDim. If not, see <http://www.gnu.org/licenses/> */ package uk.co.danielrendall.fractdim.calculation.grids; import java.util.Map; import java.util.HashMap; /** * @author Daniel Rendall * @created 30-May-2009 19:25:42 */ public class GridSquare implements Comparable<GridSquare> { static final int NO_TOUCH = -1; static final int SAME = 0; static final int ABOVE_LEFT = 1; static final int ABOVE = 2; static final int ABOVE_RIGHT = 3; static final int RIGHT = 4; static final int BELOW_RIGHT = 5; static final int BELOW = 6; static final int BELOW_LEFT = 7; static final int LEFT = 8; static final Map<String, GridSquare> squares = new HashMap<String, GridSquare>(); // maybe better to have a factory method which returns flyweight squares? public static int createCount = 0; private final int xIndex, yIndex; private final int hashCode; private GridSquare(int xIndex, int yIndex) { this.xIndex = xIndex; this.yIndex = yIndex; hashCode = xIndex << 16 | (yIndex & 0xffff); createCount++; } public static GridSquare create(int xIndex, int yIndex) { String key = "" + xIndex + "," + yIndex; GridSquare square = squares.get(key); if (square == null) { square = new GridSquare(xIndex, yIndex); squares.put(key, square); } return square; } public static void resetCount() { createCount = 0; squares.clear(); } public int x() { return xIndex; } public int y() { return yIndex; } @Override public int hashCode() { return hashCode; } @Override public boolean equals(Object obj) { if (obj instanceof GridSquare) { GridSquare other = (GridSquare) obj; return (this.xIndex == other.xIndex && this.yIndex == other.yIndex); } return false; } @Override public String toString() { return String.format("(%d, %d)", xIndex, yIndex); } /** * Returns an int indicating how 'another' is related spacially to this pixel. If they are the same, then 0 * is returned. If they are touching (either adjacent or diagonal), the number is: * <p/> * 1 2 3 * 8 4 * 7 6 5 * <p/> * I.e. '3' means that 'another' is above and to the right of this one. * <p/> * If they are not touching, -1 is returned * * @param another * @return */ int direction(GridSquare another) { int xDiff = another.xIndex - xIndex; // +ve other is to the right, 0 = same, -ve other to the left int yDiff = another.yIndex - yIndex; // +ve other is below, 0 = same, -ve = other is above switch (yDiff) { case -1: switch (xDiff) { case -1: return ABOVE_LEFT; case 0: return ABOVE; case 1: return ABOVE_RIGHT; default: return NO_TOUCH; } case 0: switch (xDiff) { case -1: return LEFT; case 0: return SAME; case 1: return RIGHT; default: return NO_TOUCH; } case 1: switch (xDiff) { case -1: return BELOW_LEFT; case 0: return BELOW; case 1: return BELOW_RIGHT; default: return NO_TOUCH; } default: return NO_TOUCH; } } public int compareTo(GridSquare other) { int yDiff = yIndex - other.yIndex; if (yDiff != 0) return yDiff; return xIndex - other.xIndex; } }