package edu.stanford.hci.flowmap.cluster;
import org.codemap.util.geom.Point2D;
/**
* Utility class for working with 2D Vectors
* @author dphan
*
* This software is distributed under the Berkeley Software Distribution License.
* Please see http://graphics.stanford.edu/~dphan/code/bsd.license.html
*
*/
public class Vector2D {
private Point2D from, to, normalized;
/**
* Constructs a Vector2D from two Point2D objects
* @param from
* @param to
*/
public Vector2D(Point2D from, Point2D to) {
this.from = from;
this.to = to;
double x, y, dist;
normalized = new Point2D.Double(0,0);
x = to.getX() - from.getX();
y = to.getY() - from.getY();
dist = Math.sqrt(x*x+y*y);
x /= dist;
y /= dist;
normalized.setLocation(x,y);
}
public Point2D getFrom() {
return from;
}
public Point2D getTo() {
return to;
}
public String toString() {
return from + " --> " + to;
}
public Point2D getNormalized() {
return normalized;
}
public double dotProduct(Vector2D other) {
Point2D otherNorm = other.getNormalized();
return normalized.getX()*otherNorm.getX() + normalized.getY()*otherNorm.getY();
}
public double angleBetween(Vector2D other) {
double dotValue = dotProduct(other);
if (dotValue >= 1)
dotValue = 1;
else if (dotValue <= -1)
dotValue = -1;
return Math.acos(dotValue);
}
public double absAngleBetween(Vector2D other) {
double angleBetw = angleBetween(other);
// remember that for a vector (a,b)
// and that the perpendicular vector is (-b,a)
// now just dot perpendicular vector with the other vector,
// if it is positive, do nothing,
// if it is negative, add Math.PI
Point2D otherNorm = other.getNormalized();
double dot = -normalized.getY()*otherNorm.getX() + normalized.getX()*otherNorm.getY();
if (dot >= 0)
return angleBetw;
else
return 2*Math.PI - angleBetw;
}
}