package com.pointcliki.grid;
import java.io.Serializable;
import org.newdawn.slick.geom.Vector2f;
/**
* Contains an (x, y) integer pair to represent a discrete coordinate on a 2d plane
*
* @author hugheth
* @since 1
*/
public class GridCoordinate implements Serializable, Cloneable {
/**
* Serial key
*/
private static final long serialVersionUID = 4408149349085315269L;
public static final GridCoordinate ZERO = new GridCoordinate(0, 0);
public static final GridCoordinate NORTH = new GridCoordinate(0, -1);
public static final GridCoordinate EAST = new GridCoordinate(1, 0);
public static final GridCoordinate SOUTH = new GridCoordinate(0, 1);
public static final GridCoordinate WEST = new GridCoordinate(-1, 0);
public static final GridCoordinate NORTH_EAST = new GridCoordinate(1, -1);
public static final GridCoordinate SOUTH_EAST = new GridCoordinate(1, 1);
public static final GridCoordinate SOUTH_WEST = new GridCoordinate(-1, 1);
public static final GridCoordinate NORTH_WEST = new GridCoordinate(-1, -1);
public static final String[] COMPASS = new String[] {"NORTH", "EAST", "SOUTH", "WEST"};
public static final String[] DIAGONAL_COMPASS = new String[] {"NORTHEAST", "SOUTHEAST", "SOUTHWEST", "NORTHWEST"};
protected int fX;
protected int fY;
public GridCoordinate(int x, int y) {
fX = x;
fY = y;
}
public GridCoordinate(Vector2f v) {
fX = (int) v.x;
fY = (int) v.y;
}
@Override
public boolean equals(Object o) {
return (o instanceof GridCoordinate && fX == ((GridCoordinate)o).fX && fY == ((GridCoordinate)o).fY);
}
public GridCoordinate clone() {
return new GridCoordinate(fX, fY);
}
public GridCoordinate add(GridCoordinate other) {
return new GridCoordinate(fX + other.fX, fY + other.fY);
}
public GridCoordinate subtract(GridCoordinate other) {
return new GridCoordinate(fX - other.fX, fY - other.fY);
}
public String toString() {
return "(" + fX + ", " + fY + ")";
}
public String toName() {
if (this.equals(GridCoordinate.NORTH)) return "NORTH";
else if (this.equals(GridCoordinate.EAST)) return "EAST";
else if (this.equals(GridCoordinate.SOUTH)) return "SOUTH";
else if (this.equals(GridCoordinate.WEST)) return "WEST";
else if (this.equals(GridCoordinate.NORTH_EAST)) return "NORTHEAST";
else if (this.equals(GridCoordinate.SOUTH_EAST)) return "SOUTHEAST";
else if (this.equals(GridCoordinate.SOUTH_WEST)) return "SOUTHWEST";
else if (this.equals(GridCoordinate.NORTH_WEST)) return "NORTHWEST";
else if (this.equals(GridCoordinate.ZERO)) return "ZERO";
return "OTHER";
}
public static GridCoordinate fromString(String s) {
if (s.equals("NORTH")) return NORTH;
else if (s.equals("EAST")) return EAST;
else if (s.equals("SOUTH")) return SOUTH;
else if (s.equals("WEST")) return WEST;
else if (s.equals("NORTHEAST")) return NORTH_EAST;
else if (s.equals("SOUTHEAST")) return SOUTH_EAST;
else if (s.equals("SOUTHWEST")) return SOUTH_WEST;
else if (s.equals("NORTHWEST")) return NORTH_WEST;
else if (s.equals("ZERO")) return ZERO;
return null;
}
public int x() {
return fX;
}
public int y() {
return fY;
}
@Override
public int hashCode() {
return fX * 256 + fY;
}
public Vector2f toVector2f() {
return new Vector2f(fX, fY);
}
public Vector2f multiplyPartsByVector(Vector2f factor) {
Vector2f v = new Vector2f(0, 0);
v.x = fX * factor.x;
v.y = fY * factor.y;
return v;
}
public boolean adjacent(GridCoordinate xy) {
return (Math.abs(xy.x() - fX) < 2 && Math.abs(xy.y() - fY) < 2);
}
public GridCoordinate max(GridCoordinate tile) {
return new GridCoordinate(Math.max(fX, tile.fX), Math.min(fY, tile.fY));
}
public GridCoordinate multiply(float scalar) {
return new GridCoordinate((int) Math.floor(fX * scalar), (int) Math.floor(fY * scalar));
}
public int manhattanDistance(GridCoordinate xy) {
return Math.abs(xy.x() - fX) + Math.abs(xy.y() - fY);
}
public float distance(GridCoordinate xy) {
return (float) Math.sqrt(Math.pow(Math.abs(xy.x() - fX), 2) + Math.pow(Math.abs(xy.y() - fY), 2));
}
public boolean isDiagonal() {
return fX == fY || fX == -fY;
}
}