Vector2D | Vector3D
Vector2D stores a mathematical vector in 2 dimensions. You can create it from cartesian (x, y) with new Vector2D(x, y)
or polar (r, θ) with Vector2D.fromPolar2D(r, theta)
, where "theta" is an Angle object.
Vector2D has 4 getters:
double getX()
double getY()
double getLength()
- Angle
getDirection()
A static method to compute the dot product of two Vector2D objects.
public static double dotProduct(Vector2D v1, Vector2D v2)
And a static method to find the signed separation between vectors.
public static Angle signedAngularSeparation(Vector2D ref, Vector2D vector)
signedAngularSeparation can be very useful when dealing with a gyro sensor that can wrap around from 360 to 0. It returns an Angle object.
ftc/electronvolts/util/Vector2D.java
package ftc.electronvolts.util;
import ftc.electronvolts.util.units.Angle;
/**
* This file was made by the electronVolts, FTC team 7393
* Date Created: 10/1/16
*/
public class Vector2D {
/*
* the 2 components of the vector
*/
private final double x;
private final double y;
/*
* the polar coordinates
*/
private final double l;
private final Angle theta;
/**
* create a vector using polar coordinates
*
* @param magnitude the magnitude of the 2-D vector
* @param theta the direction of the 2-D vector
* @return the created vector
*/
public Vector2D(double magnitude, Angle theta) {
double thetaRads = theta.radians();
this.x = magnitude * Math.cos(thetaRads);
this.y = magnitude * Math.sin(thetaRads);
this.l = magnitude;
this.theta = theta;
}
/**
* create a vector using x and y
*
* @param x x component
* @param y y component
*/
public Vector2D(double x, double y) {
this.x = x;
this.y = y;
//Pythagorean theorem
this.l = Math.sqrt(x * x + y * y);
this.theta = Angle.fromRadians(Math.atan2(y, x));
}
/**
* @return the x component of the vector
*/
public double getX() {
return x;
}
/**
* @return the y component of the vector
*/
public double getY() {
return y;
}
/**
* @return the length or magnitude of the vector
*/
public double getLength() {
return l;
}
/**
* @return a new vector that is normalized (length = 1)
*/
public Vector2D normalized() {
return new Vector2D(x / l, y / l);
}
/**
* The order does not matter for the dot product
*
* @param v1 one vector
* @param v2 another vector
* @return the dot product of the two vectors
*/
public static double dotProduct(Vector2D v1, Vector2D v2) {
return v1.x * v2.x + v1.y * v2.y;
}
/**
* @return the direction of the vector
*/
public Angle getDirection() {
return theta;
}
private final static double closeToZero = 1.0e-3;
/**
* This helps when using a gyro sensor or any type of 360 degree rotation
* mechanism
*
* @param ref the reference direction, assumed to have no z component
* @param vector the vector to be measured against the reference to find the
* angular separation, also assumed to have no z component
* @return angular separation between -pi and pi. If vector is to the right
* of reference, then it is positive.
*/
public static Angle signedAngularSeparation(Vector2D ref, Vector2D vector) {
Vector3D ref3D = Vector3D.from2D(ref);
Vector3D vector3D = Vector3D.from2D(vector);
Vector3D cross = Vector3D.crossProduct(ref3D, vector3D);
// If the vectors are too closely aligned, then return zero for
// separation.
if (Math.abs(cross.getZ()) < closeToZero) {
return Angle.zero();
}
// To get the angle:
// a dot b = a * b * cos(angle)
// so angle = acos[ (a dot b) / (a * b) ]
// Make sure a * b is not too close to zero 0
double lengths = ref3D.getLength() * vector3D.getLength();
if (lengths < closeToZero) {
// this is really an error, but to keep the robot from crashing,
// just return 0
return Angle.zero();
}
double dot = Vector3D.dotProduct(ref3D, vector3D);
return Angle.fromRadians(Math.signum(cross.getZ()) * Math.acos(dot / lengths));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(x);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(y);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Vector2D other = (Vector2D) obj;
if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x)) return false;
if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y)) return false;
return true;
}
@Override
public String toString() {
return "(" + x + ", " + y + ")";
}
}