package jaci.openrio.toast.lib.math; /** * A simple class representing a 2D Vector. This class is capable of all the relevant mathematical operations for * a 2D vector. * * @author Jaci */ public class Vec2D { private double x = 0, y = 0; public Vec2D() { } /** * Create a new 2D Vector with the given x and y components */ public Vec2D(double x, double y) { this.x = x; this.y = y; } /** * Clone a 2D Vector Instance */ public Vec2D(Vec2D clone) { this(clone.x(), clone.y()); } // -- STATICS -- // /** * Create a 2D Vector from an angle relative to the positive x-axis and a magnitude * @param angleInDegrees The angle relative to the positive x-axis in Degrees * @param magnitude The magnitude of the vector */ public static Vec2D fromDegrees(double angleInDegrees, double magnitude) { double x = magnitude * Math.cos(angleInDegrees * Math.PI / 180); double y = magnitude * Math.sin(angleInDegrees * Math.PI / 180); return new Vec2D(x, y); } /** * Create a 2D Vector from an angle relative to the positive y-axis and a magnitude * @param angleInDegrees The angle relative to the positive y-axis in Degrees (Clockwise on a Clock) * @param magnitude The magnitude of the vector */ public static Vec2D fromDegrees2(double angleInDegrees, double magnitude) { double x = magnitude * Math.sin(angleInDegrees * Math.PI / 180); double y = magnitude * Math.cos(angleInDegrees * Math.PI / 180); return new Vec2D(x, y); } /** * Create a 2D Vector from an angle relative to the positive x-axis and a magnitude * @param angleInRad The angle relative to the positive x-axis in Radians * @param magnitude The magnitude of the vector */ public static Vec2D fromRadians(double angleInRad, double magnitude) { double x = magnitude * Math.cos(angleInRad); double y = magnitude * Math.sin(angleInRad); return new Vec2D(x, y); } /** * Create a 2D Vector from an angle relative to the positive y-axis and a magnitude * @param angleInRad The angle relative to the positive y-axis in Radians (Clockwise on a Clock) * @param magnitude The magnitude of the vector */ public static Vec2D fromRadians2(double angleInRad, double magnitude) { double x = magnitude * Math.sin(angleInRad); double y = magnitude * Math.cos(angleInRad); return new Vec2D(x, y); } // -- INSTANCE -- // /** * @return The x component of the 2D Vector */ public double x() { return x; } /** * @return The y component of the 2D Vector */ public double y() { return y; } /** * Set the x-component of the 2D Vector * @param newX The new x component of the 2D Vector */ public void setX(double newX) { this.x = newX; } /** * Set the y-component of the 2D Vector * @param newY The new y component of the 2D Vector */ public void setY(double newY) { this.y = newY; } /** * @return The magnitude of the 2D Vector */ public double magnitude() { return Math.sqrt(x() * x() + y() * y()); } /** * @return The heading relative to the positive x-axis in the form of Degrees. */ public double heading() { return Math.atan2(y(), x()) * 180 / Math.PI; } /** * @return The heading relative to the positive x-axis in the form of Radians. */ public double headingRad() { return Math.atan2(y(), x()); } /** * @return The heading relative to the positive y-axis in the form of Degrees (Clockwise on a Clock) */ public double heading2() { return Math.atan2(x(), y()) * 180 / Math.PI; } /** * @return The heading relative to the positive y-axis in the form of Degrees (Clockwise on a Clock) */ public double headingRad2() { return Math.atan2(x(), y()); } /** * @return A 2D Vector of magnitude 1 and heading of the original 2D Vector */ public Vec2D toUnitVector() { double mag = magnitude(); return new Vec2D(x() / mag, y() / mag); } /** * Multiply this 2D Vector by a Scalar value * @param scalar The scalar value to multiply by */ public Vec2D multiply(double scalar) { return new Vec2D(x() * scalar, y() * scalar); } /** * Subtract another 2D Vector from this 2D Vector * @param otherVector The vector to subtract from this vector */ public Vec2D subtract(Vec2D otherVector) { return new Vec2D(x() - otherVector.x(), y() - otherVector.y()); } /** * Add this 2D Vector to another 2D Vector * @param otherVector The vector to add to this vector */ public Vec2D add(Vec2D otherVector) { return new Vec2D(x() + otherVector.x(), y() + otherVector.y()); } /** * Calculate the Dot Product of this 2D Vector * @param otherVector The vector to dot product against * @return The scalar Dot Product of the Vectors */ public double dot(Vec2D otherVector) { return x() * otherVector.x() + y() * otherVector.y(); } /** * Calculate the Vector Projection of this Vector onto another Vector * @param otherVector The vector to project onto */ public Vec2D projectOnto(Vec2D otherVector) { return otherVector.multiply(dot(otherVector) / otherVector.dot(otherVector)); } /** * Calculate the Scalar Projection of this Vector onto another Vector * @param otherVector The vector to project onto */ public double scalarProjectOnto(Vec2D otherVector) { return dot(otherVector) / otherVector.magnitude(); } /** * Calculate this vector relative to another vector * @param otherVector The vector 'viewing' this vector */ public Vec2D relativeTo(Vec2D otherVector) { return subtract(otherVector); } /** * Represent a 2D Vector in String form */ public String toString() { return String.format("(%.2f, %.2f)", x(), y()); // 2 Decimal Places } }