/* * Created on Nov 14, 2006 */ package ecologylab.serialization.library.geom; import java.awt.geom.Point2D; import ecologylab.serialization.annotations.simpl_scalar; /** * @author Zachary O. Toups (toupsz@cs.tamu.edu) */ public class Vector2d extends SpatialVector implements Cloneable { /** * Adds two vectors together and returns a new Vector2d object representing the sum. * * @param v1 * @param v2 * @return */ public static Vector2d add(Vector2d v1, Vector2d v2) { return new Vector2d(v1.getX() + v2.getX(), v1.getY() + v2.getY()); } /** * Multiplies a vector by a scalar value and returns a new Vector2d representing the result. * * @param vector * @param scalar * @return */ public static Vector2d scalarMultiply(Vector2d vector, double scalar) { return new Vector2d(vector.getX() * scalar, vector.getY() * scalar); } /** * Determines the dot product of two vector objects. * * @param v1 * @param v2 * @return */ public static double dot(Vector2d v1, Vector2d v2) { return (v1.getX() * v2.getX()) + (v1.getY() * v2.getY()); } /** * Subtracts v2 from v1 and returns a new Vector2d representing the result. * * @param v1 * @param v2 * @return */ public static Vector2d sub(SpatialVector v1, SpatialVector v2) { return new Vector2d(v1.getX() - v2.getX(), v1.getY() - v2.getY()); } protected @simpl_scalar double x; protected @simpl_scalar double y; protected Point2D.Double point = null; /** * */ public Vector2d() { super(); // zero(); } public Vector2d(double x, double y) { this.x = x; this.y = y; } public Vector2d(Vector2d otherVect) { x = otherVect.getX(); y = otherVect.getY(); } public void add(Vector2d v) { this.scaledAdd(v, 1.0); } /** * Scale a vector and add it to this. * * @param v * the vector to be scaled and added to this. * @param scale * the scale for the vector to be added. */ public void scaledAdd(Vector2d v, double scale) { this.x += v.getX() * scale; this.y += v.getY() * scale; updatePointIfNotNull(); } public double norm() { return Math.sqrt(x * x + y * y); } public void mult(double scalar) { this.x *= scalar; this.y *= scalar; updatePointIfNotNull(); } /** * Rotates this vector around the origin by the specified angle in degrees. * * @param angle * - in radians */ public void rotate(double angle) { double cos = Math.cos(angle); double sin = Math.sin(angle); double x1 = this.x; double y1 = this.y; this.x = (x1 * cos) - (y1 * sin); this.y = (y1 * cos) + (x1 * sin); updatePointIfNotNull(); } /** * Rotates this vector so that it is aligned to the specified angle in radians. * * @param angle * - in radians */ public void rotateTo(double angle) { // TODO gotta make this more efficient! this.rotate(angle - this.toRadians()); } public void sub(Vector2d v) { this.x -= v.getX(); this.y -= v.getY(); updatePointIfNotNull(); } /** * Converts the vector into a radian angle. If the result would be NaN, returns 0. * * @return */ public double toRadians() { double result = Math.atan2(y, x); if (Double.isNaN(result)) result = 0; return result; } public Vector2d unitVector() { double mag = this.norm(); return new Vector2d(this.x / mag, this.y / mag); } public void unitize() { double mag = this.norm(); this.set(this.x / mag, this.y / mag); } /** * @see java.lang.Object#clone() */ @Override public Vector2d clone() { return new Vector2d(this); } public void set(Vector2d pos) { this.set(pos.getX(), pos.getY()); } @Override public Point2D toPoint() { if (this.point == null) point = new Point2D.Double(x, y); return point; } /** * @see ecologylab.generic.Debug#toString() */ @Override public String toString() { return "(" + x + ", " + y + ")"; } /** * Adjusts the magnitude of this vector to match mag. * * @param mag */ public void setNorm(double mag) { this.unitize(); this.mult(mag); } public void zero() { x = 0; y = 0; } public void set(double x, double y) { this.x = x; this.y = y; updatePointIfNotNull(); } /** * @param x */ private void updatePointIfNotNull() { if (this.point != null) { synchronized (point) { point.setLocation(x, y); } } } /** * @param y * the y to set */ public void setX(double x) { this.x = x; updatePointIfNotNull(); } /** * @param y * the y to set */ public void setY(double y) { this.y = y; updatePointIfNotNull(); } /** * @return the x */ @Override public double getX() { return x; } /** * @return the y */ @Override public double getY() { return y; } public void add(double x, double y) { this.x += x; this.y += y; updatePointIfNotNull(); } }