package wecui.util;
/**
* Represents a 3d vector.
*/
public class Vector3 implements Comparable<Vector3> {
/**
* Vector with all elements set to 0. (0, 0, 0)
*/
public final static Vector3 ZERO = new Vector3(0, 0, 0);
/**
* Unit Vector in the X direction. (1, 0, 0)
*/
public final static Vector3 UNIT_X = new Vector3(1, 0, 0);
/**
* Unit Vector facing Forward. (1, 0, 0)
*/
public final static Vector3 Forward = UNIT_X;
/**
* Unit Vector in the Y direction. (0, 1, 0)
*/
public final static Vector3 UNIT_Y = new Vector3(0, 1, 0);
/**
* Unit Vector pointing Up. (0, 1, 0)
*/
public final static Vector3 Up = UNIT_Y;
/**
* Unit Vector in the Z direction. (0, 0, 1)
*/
public final static Vector3 UNIT_Z = new Vector3(0, 0, 1);
/**
* Unit Vector pointing Right. (0, 0, 1)
*/
public final static Vector3 Right = UNIT_Z;
/**
* Unit Vector with all elements set to 1. (1, 1, 1)
*/
public final static Vector3 ONE = new Vector3(1, 1, 1);
protected float x, y, z;
/**
* Constructs a new Vector3 with the given x, y, z
*
* @param x
* @param y
* @param z
*/
public Vector3(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* Constructs a new Vector3 with the given x, y, z
*
* @param x
* @param y
* @param z
*/
public Vector3(Double x, Double y, Double z) {
this(x.floatValue(), y.floatValue(), z.floatValue());
}
/**
* Constructs a new Vector3 with all elements set to 0
*/
public Vector3() {
this(0, 0, 0);
}
/**
* Constructs a new Vector3 that is a clone of the given vector3
*
* @param clone
*/
public Vector3(Vector3 clone) {
this(clone.getX(), clone.getY(), clone.getZ());
}
/**
* Constructs a new Vector3 from the given Vector2 and z
*
* @param vector
* @param z
*/
public Vector3(Vector2 vector, float z) {
this(vector.getX(), vector.getY(), z);
}
/**
* Constructs a new Vector3 from the given Vector2 and z set to 0
*
* @param vector
*/
public Vector3(Vector2 vector) {
this(vector, 0);
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public float getZ() {
return z;
}
/**
* Adds two vectors
*
* @param that
* @return
*/
public Vector3 add(Vector3 that) {
return Vector3.add(this, that);
}
/**
* Subtracts two vectors
*
* @param that
* @return
*/
public Vector3 subtract(Vector3 that) {
return Vector3.subtract(this, that);
}
/**
* Scales by the scalar value
*
* @param scale
* @return
*/
public Vector3 scale(float scale) {
return Vector3.scale(this, scale);
}
/**
* Takes the dot product of two vectors
*
* @param that
* @return
*/
public float dot(Vector3 that) {
return Vector3.dot(this, that);
}
/**
* Takes the cross product of two vectors
*
* @param that
* @return
*/
public Vector3 cross(Vector3 that) {
return Vector3.cross(this, that);
}
/**
* Returns a Vector2 object using the X and Z values of
* this Vector3. The x of this Vector3 becomes the x
* of the Vector2, and the z of this Vector3 becomes the
* y of the Vector2.
*
* @return
*/
public Vector2 toVector2() {
return Vector3.toVector2(this);
}
/**
* Returns a Vector2m object using the X and Z values of
* this Vector3. The x of this Vector3 becomes the x
* of the Vector2, and the z of this Vector3 becomes the
* y of the Vector2m.
*
* @return
*/
public Vector2m toVector2m() {
return Vector3.toVector2m(this);
}
/**
* Rounds the X, Y, and Z values of this Vector3 up to
* the nearest integer value.
*
* @return
*/
public Vector3 ceil() {
return new Vector3(Math.ceil(x), Math.ceil(y), Math.ceil(z));
}
/**
* Rounds the X, Y, and Z values of this Vector3 down to
* the nearest integer value.
*
* @return
*/
public Vector3 floor() {
return new Vector3(Math.floor(x), Math.floor(y), Math.floor(z));
}
/**
* Rounds the X, Y, and Z values of this Vector3 to
* the nearest integer value.
*
* @return
*/
public Vector3 round() {
return new Vector3(Math.round(x), Math.round(y), Math.round(z));
}
/**
* Sets the X, Y, and Z values of this Vector3 to their
* absolute value.
*
* @return
*/
public Vector3 abs() {
return new Vector3(Math.abs(x), Math.abs(y), Math.abs(z));
}
/**
* Gets the distance between this Vector3 and a given Vector3.
*
* @param a
* @return
*/
public double distance(Vector3 a) {
return Vector3.distance(a, this);
}
/**
* Raises the X, Y, and Z values of this Vector3 to the given power.
*
* @param power
* @return
*/
public Vector3 pow(double power) {
return Vector3.pow(this, power);
}
/**
* returns the squared length of the vector
*
* @return
*/
public float lengthSquared() {
return Vector3.lengthSquared(this);
}
/**
* returns the length of this vector. Note: makes use of Math.sqrt and is
* not cached.
*
* @return
*/
public float length() {
return Vector3.length(this);
}
/**
* Returns a fast approximation of this vector's length.
*
* @return
*/
public float fastLength() {
return Vector3.fastLength(this);
}
/**
* returns the vector with a length of 1
*
* @return
*/
public Vector3 normalize() {
return Vector3.normalize(this);
}
/**
* returns the vector as [x,y,z]
*
* @return
*/
public float[] toArray() {
return Vector3.toArray(this);
}
/**
* Compares two Vector3s
*/
public int compareTo(Vector3 o) {
return Vector3.compareTo(this, o);
}
/**
* Checks if two Vector3s are equal
*/
public boolean equals(Object o) {
return Vector3.equals(this, o);
}
/**
* toString Override
*/
public String toString() {
return String.format("{ %f, %f, %f }", x, y, z);
}
/**
* Returns the length of the given vector.
*
* Note: Makes use of Math.sqrt and
* is not cached, so can be slow
*
* Also known as norm. ||a||
*
* @param a
* @return
*/
public static float length(Vector3 a) {
return (float) Math.sqrt(lengthSquared(a));
}
/**
* Returns an approximate length of the given vector.
*
* @param a
* @return
*/
public static float fastLength(Vector3 a) {
return (float) Math.sqrt(lengthSquared(a));
}
/**
* returns the length squared to the given vector
*
* @param a
* @return
*/
public static float lengthSquared(Vector3 a) {
return Vector3.dot(a, a);
}
/**
* Returns a new vector that is the given vector but length 1
*
* @param a
* @return
*/
public static Vector3 normalize(Vector3 a) {
return Vector3.scale(a, (1.f / a.length()));
}
/**
* Creates a new vector that is A - B
*
* @param a
* @param b
* @return
*/
public static Vector3 subtract(Vector3 a, Vector3 b) {
return new Vector3(a.getX() - b.getX(), a.getY() - b.getY(), a.getZ() - b.getZ());
}
/**
* Creates a new Vector that is A + B
*
* @param a
* @param b
* @return
*/
public static Vector3 add(Vector3 a, Vector3 b) {
return new Vector3(a.getX() + b.getX(), a.getY() + b.getY(), a.getZ() + b.getZ());
}
/**
* Creates a new vector that is A multiplied by the uniform scalar B
*
* @param a
* @param b
* @return
*/
public static Vector3 scale(Vector3 a, float b) {
return new Vector3(a.getX() * b, a.getY() * b, a.getZ() * b);
}
/**
* Returns the dot product of A and B
*
* @param a
* @param b
* @return
*/
public static float dot(Vector3 a, Vector3 b) {
return a.getX() * b.getX() + a.getY() * b.getY() + a.getZ() * b.getZ();
}
/**
* Creates a new Vector that is the A x B The Cross Product is the vector
* orthogonal to both A and B
*
* @param a
* @param b
* @return
*/
public static Vector3 cross(Vector3 a, Vector3 b) {
return new Vector3(a.getY() * b.getZ() - a.getZ() * b.getY(), a.getZ() * b.getX() - a.getX() * b.getZ(), a.getX() * b.getY() - a.getY() * b.getX());
}
/**
* Rounds the X, Y, and Z values of the given Vector3 up to
* the nearest integer value.
*
* @param o Vector3 to use
* @return
*/
public static Vector3 ceil(Vector3 o) {
return new Vector3(Math.ceil(o.x), Math.ceil(o.y), Math.ceil(o.z));
}
/**
* Rounds the X, Y, and Z values of the given Vector3 down to
* the nearest integer value.
*
* @param o Vector3 to use
* @return
*/
public static Vector3 floor(Vector3 o) {
return new Vector3(Math.floor(o.x), Math.floor(o.y), Math.floor(o.z));
}
/**
* Rounds the X, Y, and Z values of the given Vector3 to
* the nearest integer value.
*
* @param o Vector3 to use
* @return
*/
public static Vector3 round(Vector3 o) {
return new Vector3(Math.round(o.x), Math.round(o.y), Math.round(o.z));
}
/**
* Sets the X, Y, and Z values of the given Vector3 to their
* absolute value.
*
* @param o Vector3 to use
* @return
*/
public static Vector3 abs(Vector3 o) {
return new Vector3(Math.abs(o.x), Math.abs(o.y), Math.abs(o.z));
}
/**
* Returns a Vector3 containing the smallest X, Y, and Z values.
*
* @param o1
* @param o2
* @return
*/
public static Vector3 min(Vector3 o1, Vector3 o2) {
return new Vector3(Math.min(o1.x, o2.x), Math.min(o1.y, o2.y), Math.min(o1.z, o2.z));
}
/**
* Returns a Vector3 containing the largest X, Y, and Z values.
*
* @param o1
* @param o2
* @return
*/
public static Vector3 max(Vector3 o1, Vector3 o2) {
return new Vector3(Math.max(o1.x, o2.x), Math.max(o1.y, o2.y), Math.max(o1.z, o2.z));
}
/**
* Returns a Vector3 with random X, Y, and Z values (between 0 and 1)
*
* @return
*/
public static Vector3 rand() {
return new Vector3(Math.random(), Math.random(), Math.random());
}
/**
* Gets the distance between two Vector3.
*
* @param a
* @param b
* @return
*/
public static double distance(Vector3 a, Vector3 b) {
double xzDist = Vector2.distance(a.toVector2(), b.toVector2());
return Math.sqrt(Math.pow(xzDist, 2) + Math.pow(Math.abs(Vector3.subtract(a, b).getY()), 2));
}
/**
* Raises the X, Y, and Z values of a Vector3 to the given power.
*
* @param o
* @param power
* @return
*/
public static Vector3 pow(Vector3 o, double power) {
return new Vector3(Math.pow(o.x, power), Math.pow(o.y, power), Math.pow(o.z, power));
}
/**
* Returns a Vector2 object using the X and Z values of
* the given Vector3. The x of the Vector3 becomes the x
* of the Vector2, and the z of this Vector3 becomes the
* y of the Vector2m.
*
* @param o Vector3 object to use
* @return
*/
public static Vector2 toVector2(Vector3 o) {
return new Vector2(o.x, o.z);
}
/**
* Returns a Vector2m object using the X and Z values of
* the given Vector3. The x of the Vector3 becomes the x
* of the Vector2m, and the z of this Vector3 becomes the
* y of the Vector2m.
*
* @param o Vector3 object to use
* @return
*/
public static Vector2m toVector2m(Vector3 o) {
return new Vector2m(o.x, o.z);
}
/**
* Returns a new float array that is {x, y, z}
*
* @param a
* @return
*/
public static float[] toArray(Vector3 a) {
return new float[]{a.getX(), a.getY(), a.getZ()};
}
/**
* Compares two Vector3s
*/
public static int compareTo(Vector3 a, Vector3 b) {
return (int) a.lengthSquared() - (int) b.lengthSquared();
}
/**
* Checks if two Vector3s are equal
*/
public static boolean equals(Object a, Object b) {
if (!(a instanceof Vector3) || !(b instanceof Vector3)) {
return false;
}
if (a == b) {
return true;
}
Vector3 x = (Vector3) a;
Vector3 y = (Vector3) b;
if (x.getX() == y.getX() && x.getY() == y.getY() && x.getZ() == y.getZ()) {
return true;
}
return false;
}
}