package com.austinv11.collectiveframework.utils.math;
/**
* Class for manipulating and holding coords on a 3D plane
* Remember, in Minecraft the y and z axises are switched
*/
public class ThreeDimensionalVector implements Comparable {
private double x,y,z;
/**
* Default constructor
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
*/
public ThreeDimensionalVector(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* Sets the coordinates
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
*/
public void setComponents(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* Returns the x coord as an int
* @return The rounded x coord
*/
public int getRoundedX() {
return (int)x;
}
/**
* Returns the y coord as an int
* @return The rounded y coord
*/
public int getRoundedY() {
return (int)y;
}
/**
* Returns the z coord as an int
* @return The rounded z coord
*/
public int getRoundedZ() {
return (int)z;
}
/**
* Gets the x coord of the vector
* @return The coord
*/
public double getX() {
return x;
}
/**
* Gets the y coord of the vector
* @return The coord
*/
public double getY() {
return y;
}
/**
* Gets the z coord of the vector
* @return The coord
*/
public double getZ() {
return z;
}
/**
* Returns a new vector with the result of the specified vector minus this.
* @param other The vector to subtract from
* @return New vector
*/
public ThreeDimensionalVector subtract(ThreeDimensionalVector other) {
return new ThreeDimensionalVector(other.x - x, other.y - y, other.z - z);
}
/**
* Returns a new vector with the result of the specified vector plus this.
* @param other The vector to add to
* @return New vector
*/
public ThreeDimensionalVector add(ThreeDimensionalVector other) {
return new ThreeDimensionalVector(other.x + x, other.y + y, other.z + z);
}
/**
* Normalizes the vector to a length of 1 (all coords add up to one)
* @return Normalized vector
*/
public ThreeDimensionalVector normalize() {
double distance = Math.sqrt(dotProduct());
return distance < 1.0E-4D ? new ThreeDimensionalVector(0, 0, 0) : new ThreeDimensionalVector(x/distance, y/distance, y/distance);
}
/**
* Finds the dot product of the current vector and itself
* @return The dot product
*/
public double dotProduct() {
return x*x + y*y + z*z;
}
/**
* Finds the dot product of the current vector and the other specified vector
* @param other The other vector
* @return The dot product
*/
public double dotProduct(ThreeDimensionalVector other) {
return x*other.x + y*other.y + z*other.z;
}
/**
* Finds the cross product of the current vector and the other specified vector
* @param other The other vector
* @return The cross product
*/
public ThreeDimensionalVector crossProduct(ThreeDimensionalVector other) {
return new ThreeDimensionalVector(y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x);
}
private double squareDistanceTo(ThreeDimensionalVector other) {
return Math.pow(x-other.x, 2) + Math.pow(y-other.y, 2);
}
/**
* Finds the distance between two vectors
* @param other The other vector
* @return The distance
*/
public double distanceTo(ThreeDimensionalVector other) {
return Math.sqrt(squareDistanceTo(other));
}
/**
* Finds the length of the vector
* @return The length
*/
public double length() {
return Math.sqrt(dotProduct());
}
/**
* Returns a vector representing the midpoint between the current vector and another
* @param other The other vector
* @return The midpoint
*/
public ThreeDimensionalVector midpoint(ThreeDimensionalVector other) {
return new ThreeDimensionalVector((other.x + x)/2, (other.y + y)/2, (other.z + z)/2);
}
/**
* Rotates the vector around the X-axis
* @param center The coordinate to rotate around
* @param angle The angle to rotate by
* @return The rotated vector
*/
public ThreeDimensionalVector rotateX(ThreeDimensionalVector center, double angle) {
return new ThreeDimensionalVector(x,
Math.cos(Math.toRadians(angle))*(y-center.y)-Math.sin(Math.toRadians(angle))*(z-center.z)+center.z,
Math.sin(Math.toRadians(angle))*(y-center.y)+Math.cos(Math.toRadians(angle))*(z-center.z)+center.z);
}
/**
* Rotates the vector around the X-axis about the origin
* @param angle The angle to rotate by
* @return The rotated vector
*/
public ThreeDimensionalVector rotateX(double angle) {
return rotateX(new ThreeDimensionalVector(0, 0, 0), angle);
}
/**
* Rotates the vector around the Y-axis
* @param center The coordinate to rotate around
* @param angle The angle to rotate by
* @return The rotated vector
*/
public ThreeDimensionalVector rotateY(ThreeDimensionalVector center, double angle) {
return new ThreeDimensionalVector(Math.cos(Math.toRadians(angle))*(z-center.z)-Math.sin(Math.toRadians(angle))*(x-center.x)+center.x,
y,
Math.sin(Math.toRadians(angle))*(z-center.z)+Math.cos(Math.toRadians(angle))*(x-center.x)+center.x);
}
/**
* Rotates the vector around the Y-axis about the origin
* @param angle The angle to rotate by
* @return The rotated vector
*/
public ThreeDimensionalVector rotateY(double angle) {
return rotateY(new ThreeDimensionalVector(0, 0, 0), angle);
}
/**
* Rotates the vector around the Z-axis
* @param center The coordinate to rotate around
* @param angle The angle to rotate by
* @return The rotated vector
*/
public ThreeDimensionalVector rotateZ(ThreeDimensionalVector center, double angle) {
return new ThreeDimensionalVector(Math.cos(Math.toRadians(angle))*(x-center.x)-Math.sin(Math.toRadians(angle))*(y-center.y)+center.x,
Math.sin(Math.toRadians(angle))*(x-center.x)+Math.cos(Math.toRadians(angle))*(y-center.y)+center.y,
z);
}
/**
* Rotates the vector around the Z-axis about the origin
* @param angle The angle to rotate by
* @return The rotated vector
*/
public ThreeDimensionalVector rotateZ(double angle) {
return rotateZ(new ThreeDimensionalVector(0, 0, 0), angle);
}
/**
* Converts this vector from a 3D plane to a 2D plane
* @return The converted vector
*/
public TwoDimensionalVector to2D() {
return new TwoDimensionalVector(x, y);
}
@Override
public boolean equals(Object other) {
if (other instanceof ThreeDimensionalVector)
return ((ThreeDimensionalVector) other).x == x && ((ThreeDimensionalVector) other).y == y && ((ThreeDimensionalVector) other).z == z;
return false;
}
@Override
public String toString() {
return "ThreeDimensionalVector(X:"+x+" Y:"+y+" Z:"+z+")";
}
@Override
public int compareTo(Object o) {
ThreeDimensionalVector vector = (ThreeDimensionalVector) o;
if (vector.equals(this))
return 0;
if (vector.x == x) {
if (vector.z == z)
return vector.y > y ? -1 : 1;
return vector.z > z ? -1 : 1;
}
return vector.x > x ? -1 : 1;
}
}