package org.ripple.power.ui.graphics.geom;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.ripple.power.ui.projector.Config;
public class Vector2D implements Serializable {
/**
*
*/
private static final long serialVersionUID = -1844534518528011982L;
private static Vector2D vector2;
final static private Map<Vector2D, Integer> directions = new HashMap<Vector2D, Integer>(
9);
final static private Map<Integer, Vector2D> directionValues = new HashMap<Integer, Vector2D>(
9);
public static int getDirection(int x, int y) {
return getDirection(x, y, Config.EMPTY);
}
public static int getDirection(int x, int y, int value) {
if (vector2 == null) {
vector2 = new Vector2D(x, y);
} else {
vector2.set(x, y);
}
Integer result = directions.get(vector2);
if (result != null) {
return result;
} else {
return value;
}
}
public static Vector2D getDirection(int type) {
return directionValues.get(type);
}
static {
directions.put(new Vector2D(0, 0), Config.EMPTY);
directions.put(new Vector2D(1, -1), Config.UP);
directions.put(new Vector2D(-1, -1), Config.LEFT);
directions.put(new Vector2D(1, 1), Config.RIGHT);
directions.put(new Vector2D(-1, 1), Config.DOWN);
directions.put(new Vector2D(0, -1), Config.TUP);
directions.put(new Vector2D(-1, 0), Config.TLEFT);
directions.put(new Vector2D(1, 0), Config.TRIGHT);
directions.put(new Vector2D(0, 1), Config.TDOWN);
directionValues.put(Config.EMPTY, new Vector2D(0, 0));
directionValues.put(Config.UP, new Vector2D(1, -1));
directionValues.put(Config.LEFT, new Vector2D(-1, -1));
directionValues.put(Config.RIGHT, new Vector2D(1, 1));
directionValues.put(Config.DOWN, new Vector2D(-1, 1));
directionValues.put(Config.TUP, new Vector2D(0, -1));
directionValues.put(Config.TLEFT, new Vector2D(-1, 0));
directionValues.put(Config.TRIGHT, new Vector2D(1, 0));
directionValues.put(Config.TDOWN, new Vector2D(0, 1));
}
public double x, y;
public Vector2D(double value) {
this(value, value);
}
public Vector2D() {
this(0, 0);
}
public Vector2D(double x, double y) {
this.x = x;
this.y = y;
}
public Vector2D(Vector2D vector2D) {
this.x = vector2D.x;
this.y = vector2D.y;
}
public void move(Vector2D vector2D) {
this.x += vector2D.x;
this.y += vector2D.y;
}
public void moveX(int x) {
this.x += x;
}
public void moveY(int y) {
this.y += y;
}
public void moveByAngle(int degAngle, double distance) {
if (distance == 0) {
return;
}
double Angle = Math.toRadians(degAngle);
double dX = Math.cos(Angle) * distance;
double dY = -Math.sin(Angle) * distance;
int idX = (int) Math.round(dX);
int idY = (int) Math.round(dY);
move(idX, idY);
}
public void move(double x, double y) {
this.x += x;
this.y += y;
}
public boolean nearlyCompare(Vector2D v, int range) {
int dX = Math.abs(x() - v.x());
int dY = Math.abs(y() - v.y());
return (dX <= range) && (dY <= range);
}
public int angle(Vector2D v) {
int dx = v.x() - x();
int dy = v.y() - y();
int adx = Math.abs(dx);
int ady = Math.abs(dy);
if ((dy == 0) && (dx == 0)) {
return 0;
}
if ((dy == 0) && (dx > 0)) {
return 0;
}
if ((dy == 0) && (dx < 0)) {
return 180;
}
if ((dy > 0) && (dx == 0)) {
return 90;
}
if ((dy < 0) && (dx == 0)) {
return 270;
}
double rwinkel = Math.atan(ady / adx);
double dwinkel = 0.0D;
if ((dx > 0) && (dy > 0)) {
dwinkel = Math.toDegrees(rwinkel);
} else if ((dx < 0) && (dy > 0)) {
dwinkel = 180.0D - Math.toDegrees(rwinkel);
} else if ((dx > 0) && (dy < 0)) {
dwinkel = 360.0D - Math.toDegrees(rwinkel);
} else if ((dx < 0) && (dy < 0)) {
dwinkel = 180.0D + Math.toDegrees(rwinkel);
}
int iwinkel = (int) dwinkel;
if (iwinkel == 360) {
iwinkel = 0;
}
return iwinkel;
}
public double[] getCoords() {
return (new double[] { x, y });
}
public void setLocation(double x, double y) {
this.x = x;
this.y = y;
}
public boolean equals(Object o) {
if (o instanceof Vector2D) {
Vector2D p = (Vector2D) o;
return p.x == x && p.y == y;
}
return false;
}
public int hashCode() {
return (int) (x + y);
}
public void setX(double x) {
this.x = x;
}
public void setY(double y) {
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public int x() {
return (int) x;
}
public int y() {
return (int) y;
}
public Object clone() {
return new Vector2D(x, y);
}
public void set(Vector2D other) {
set(other.getX(), other.getY());
}
public void set(float x, float y) {
this.x = x;
this.y = y;
}
public void set(double x, double y) {
this.x = x;
this.y = y;
}
public Vector2D reverse() {
x = -x;
y = -y;
return this;
}
public float length() {
return (float) Math.sqrt(x * x + y * y);
}
public double lengthSquared() {
return (x * x) + (y * y);
}
public Vector2D add(Vector2D other) {
double x = this.x + other.x;
double y = this.y + other.y;
return new Vector2D(x, y);
}
public Vector2D addThis(Vector2D other) {
this.x += other.x;
this.y += other.y;
return this;
}
public static Vector2D sum(List<?> summands) {
Vector2D result = new Vector2D(0, 0);
for (Iterator<?> it = summands.iterator(); it.hasNext();) {
Vector2D v = (Vector2D) it.next();
result.addThis(v);
}
return result;
}
public static Vector2D sum(Vector2D a, Vector2D b) {
Vector2D answer = new Vector2D(a);
return answer.addThis(b);
}
public static Vector2D mean(List<?> points) {
int n = points.size();
if (n == 0) {
return new Vector2D(0, 0);
}
return Vector2D.sum(points).scale(1.0 / n);
}
public Vector2D sub(Vector2D v) {
x -= v.getX();
y -= v.getY();
return this;
}
public Vector2D subtract(Vector2D other) {
double x = this.x - other.x;
double y = this.y - other.y;
return new Vector2D(x, y);
}
public double dot(Vector2D vec) {
return (x * vec.x) + (y * vec.y);
}
public static double cross(Vector2D a, Vector2D b) {
return a.cross(b);
}
public double cross(Vector2D vec) {
return x * vec.y - y * vec.x;
}
public Vector2D multiply(double value) {
return new Vector2D(value * x, value * y);
}
public double dotProduct(Vector2D other) {
return other.x * x + other.y * y;
}
public Vector2D scale(double a) {
x *= a;
y *= a;
return this;
}
public Vector2D normalize() {
double magnitude = Math.sqrt(dotProduct(this));
return new Vector2D(x / magnitude, y / magnitude);
}
public double level() {
return Math.sqrt(dotProduct(this));
}
public double distanceSquared(Vector2D other) {
double dx = other.getX() - getX();
double dy = other.getY() - getY();
return (dx * dx) + (dy * dy);
}
public double distance(Vector2D other) {
return Math.sqrt(distanceSquared(other));
}
public Vector2D modulate(Vector2D other) {
double x = this.x * other.x;
double y = this.y * other.y;
return new Vector2D(x, y);
}
public boolean equalsDelta(Vector2D other, double delta) {
return (other.getX() - delta < x && other.getX() + delta > x
&& other.getY() - delta < y && other.getY() + delta > y);
}
public static Vector2D difference(Vector2D first, Vector2D second) {
Vector2D answer = new Vector2D(first);
return answer.sub(second);
}
public void rotate90() {
setLocation(y, -x);
}
public static Vector2D rotate90(Vector2D vec) {
return new Vector2D(-vec.y, vec.x);
}
public static Vector2D rotate90R(Vector2D vec) {
return new Vector2D(vec.y, -vec.x);
}
public static double dot(Vector2D a, Vector2D b) {
return a.dot(b);
}
public static double crossZ(Vector2D a, Vector2D b) {
return a.x * b.y - a.y * b.x;
}
public static Vector2D mult(Vector2D vector, double scalar) {
Vector2D answer = new Vector2D(vector);
return answer.scale(scalar);
}
public void move_multiples(int direction, int multiples) {
if (multiples <= 0) {
multiples = 1;
}
Vector2D v = getDirection(direction);
move(v.x() * multiples, v.y() * multiples);
}
public String toString() {
return (new StringBuffer("[Vector2D x:")).append(x).append(" y:")
.append(y).append("]").toString();
}
}