package pl.edu.agh.spatial;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
public class Vector {
public static enum Direction {
LEFT, RIGHT;
}
private static enum Rotation {
LEVOROTATORY, DEXTROROTATORY;
}
private static final Rotation COORDINATE_SYSTEM_ROTATION = Rotation.LEVOROTATORY;
private GeometryFactory geometryFactory;
private Point begin;
private Point end;
public Vector(Point begin, Point end, GeometryFactory geometryFactory) {
this.geometryFactory = geometryFactory;
this.begin = (Point) begin.clone();
this.end = (Point) end.clone();
}
public Vector(double dx, double dy, GeometryFactory geometryFactory) {
this.geometryFactory = geometryFactory;
this.begin = geometryFactory.createPoint(new Coordinate(0, 0));
this.end = geometryFactory.createPoint(new Coordinate(dx, dy));
}
public Point getBegin() {
return begin;
}
public Point getEnd() {
return end;
}
public Vector translate(double dx, double dy) {
this.begin.getCoordinate().x += dx;
this.begin.getCoordinate().y += dy;
this.end.getCoordinate().x += dx;
this.end.getCoordinate().y += dy;
return this;
}
public Vector translate(Vector other) {
return translate(other.getX(), other.getY());
}
public Vector translatePerpendicularly(double distance, Direction direction) {
if (distance == 0) {
return this;
}
Vector translatingVector;
if (getX() == 0) {
translatingVector = new Vector(distance, 0, geometryFactory);
} else if (getY() == 0) {
translatingVector = new Vector(0, distance, geometryFactory);
} else {
double dy = distance / Math.sqrt((getY() * getY()) / (getX() * getX()) + 1);
double dx = -(getY() / getX()) * dy;
translatingVector = new Vector(dx, dy, geometryFactory);
}
if ((determinant(this, translatingVector) > 0) == ((direction == Direction.LEFT) == (COORDINATE_SYSTEM_ROTATION == Rotation.LEVOROTATORY))) {
return translate(translatingVector);
} else {
return translate(translatingVector.reverse());
}
}
private double determinant(Vector v1, Vector v2) {
return v1.getX() * v2.getY() - v1.getY() * v2.getX();
}
public Vector reverse() {
Point point = this.begin;
this.begin = this.end;
this.end = point;
return this;
}
public double getX() {
return end.getCoordinate().x - begin.getCoordinate().x;
}
public double getY() {
return end.getCoordinate().y - begin.getCoordinate().y;
}
}