cn.nukkit.math.Vector3 Maven / Gradle / Ivy
package cn.nukkit.math;
import cn.nukkit.api.DeprecationDetails;
import cn.nukkit.api.PowerNukkitOnly;
import cn.nukkit.api.PowerNukkitXOnly;
import cn.nukkit.api.Since;
import lombok.SneakyThrows;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* @author MagicDroidX (Nukkit Project)
*/
public class Vector3 implements Cloneable {
@PowerNukkitXOnly
@Since("1.6.0.0-PNX")
public static final Vector3 ZERO = new Vector3(0, 0, 0);
public double x;
public double y;
public double z;
public Vector3() {
this(0, 0, 0);
}
public Vector3(double x) {
this(x, 0, 0);
}
public Vector3(double x, double y) {
this(x, y, 0);
}
public Vector3(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public double getX() {
return this.x;
}
public double getY() {
return this.y;
}
public double getZ() {
return this.z;
}
@Since("FUTURE")
public Vector3 setX(double x) {
this.x = x;
return this;
}
@Since("FUTURE")
public Vector3 setY(double y) {
this.y = y;
return this;
}
@Since("FUTURE")
public Vector3 setZ(double z) {
this.z = z;
return this;
}
public int getFloorX() {
return (int) Math.floor(this.x);
}
public int getFloorY() {
return (int) Math.floor(this.y);
}
public int getFloorZ() {
return (int) Math.floor(this.z);
}
public int getChunkX() {
return getFloorX() >> 4;
}
public int getChunkZ() {
return getFloorZ() >> 4;
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public int getChunkSectionY() {
return getFloorY() >> 4;
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public ChunkVector2 getChunkVector() {
return new ChunkVector2(getChunkX(), getChunkZ());
}
public double getRight() {
return this.x;
}
public double getUp() {
return this.y;
}
public double getForward() {
return this.z;
}
public double getSouth() {
return this.x;
}
public double getWest() {
return this.z;
}
public Vector3 add(double x) {
return this.add(x, 0, 0);
}
public Vector3 add(double x, double y) {
return this.add(x, y, 0);
}
public Vector3 add(double x, double y, double z) {
return new Vector3(this.x + x, this.y + y, this.z + z);
}
public Vector3 add(Vector3 x) {
return new Vector3(this.x + x.getX(), this.y + x.getY(), this.z + x.getZ());
}
@Deprecated
@DeprecationDetails(since = "1.4.0.0-PN", reason = "Makes no sense", replaceWith = "clone()")
public Vector3 subtract() {
return this.subtract(0, 0, 0);
}
public Vector3 subtract(double x) {
return this.subtract(x, 0, 0);
}
public Vector3 subtract(double x, double y) {
return this.subtract(x, y, 0);
}
public Vector3 subtract(double x, double y, double z) {
return this.add(-x, -y, -z);
}
public Vector3 subtract(Vector3 x) {
return this.add(-x.getX(), -x.getY(), -x.getZ());
}
public Vector3 multiply(double number) {
return new Vector3(this.x * number, this.y * number, this.z * number);
}
public Vector3 divide(double number) {
return new Vector3(this.x / number, this.y / number, this.z / number);
}
public Vector3 ceil() {
return new Vector3((int) Math.ceil(this.x), (int) Math.ceil(this.y), (int) Math.ceil(this.z));
}
public Vector3 floor() {
return new Vector3(this.getFloorX(), this.getFloorY(), this.getFloorZ());
}
public Vector3 round() {
return new Vector3(Math.round(this.x), Math.round(this.y), Math.round(this.z));
}
public Vector3 abs() {
return new Vector3((int) Math.abs(this.x), (int) Math.abs(this.y), (int) Math.abs(this.z));
}
public Vector3 getSide(BlockFace face) {
return this.getSide(face, 1);
}
public Vector3 getSide(BlockFace face, int step) {
return new Vector3(this.getX() + face.getXOffset() * step, this.getY() + face.getYOffset() * step, this.getZ() + face.getZOffset() * step);
}
// Get as a Vector3 for better performance. Do not override in Block!
public Vector3 getSideVec(BlockFace face) {
return new Vector3(this.getX() + face.getXOffset(), this.getY() + face.getYOffset(), this.getZ() + face.getZOffset());
}
public Vector3 up() {
return up(1);
}
public Vector3 up(int step) {
return getSide(BlockFace.UP, step);
}
public Vector3 down() {
return down(1);
}
public Vector3 down(int step) {
return getSide(BlockFace.DOWN, step);
}
public Vector3 north() {
return north(1);
}
public Vector3 north(int step) {
return getSide(BlockFace.NORTH, step);
}
public Vector3 south() {
return south(1);
}
public Vector3 south(int step) {
return getSide(BlockFace.SOUTH, step);
}
public Vector3 east() {
return east(1);
}
public Vector3 east(int step) {
return getSide(BlockFace.EAST, step);
}
public Vector3 west() {
return west(1);
}
public Vector3 west(int step) {
return getSide(BlockFace.WEST, step);
}
@PowerNukkitOnly
@Since("FUTURE")
public int distanceManhattan(Vector3 pos) {
double x = Math.abs(pos.getX() - this.getX());
double y = Math.abs(pos.getY() - this.getY());
double z = Math.abs(pos.getZ() - this.getZ());
return (int)(x + y + z);
}
public double distance(Vector3 pos) {
return distance(pos.x, pos.y, pos.z);
}
public double distanceSquared(Vector3 pos) {
return distanceSquared(pos.x, pos.y, pos.z);
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public double distance(double x, double y, double z) {
return Math.sqrt(distanceSquared(x, y, z));
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public double distanceSquared(double x, double y, double z) {
double ex = this.x - x;
double ey = this.y - y;
double ez = this.z - z;
return ex * ex + ey * ey + ez * ez;
}
public double maxPlainDistance() {
return this.maxPlainDistance(0, 0);
}
public double maxPlainDistance(double x) {
return this.maxPlainDistance(x, 0);
}
public double maxPlainDistance(double x, double z) {
return Math.max(Math.abs(this.x - x), Math.abs(this.z - z));
}
public double maxPlainDistance(Vector2 vector) {
return this.maxPlainDistance(vector.x, vector.y);
}
public double maxPlainDistance(Vector3 x) {
return this.maxPlainDistance(x.x, x.z);
}
/**
* Calculates the Length of this Vector
*
* @return The Length of this Vector.
*/
public double length() {
return Math.sqrt(this.lengthSquared());
}
public double lengthSquared() {
return this.x * this.x + this.y * this.y + this.z * this.z;
}
public Vector3 normalize() {
double len = this.lengthSquared();
if (len > 0) {
return this.divide(Math.sqrt(len));
}
return new Vector3(0, 0, 0);
}
/**
* Scalar Product of this Vector and the Vector supplied.
*
* @param v Vector to calculate the scalar product to.
* @return Scalar Product
*/
public double dot(Vector3 v) {
return this.x * v.x + this.y * v.y + this.z * v.z;
}
/**
* Calculates the cross product of this Vector and the given Vector
*
* @param v the vector to calculate the cross product with.
* @return a Vector at right angle to this and other
*/
public Vector3 cross(Vector3 v) {
return new Vector3(
this.y * v.z - this.z * v.y,
this.z * v.x - this.x * v.z,
this.x * v.y - this.y * v.x
);
}
/* PowerNukkit: The Angle class was removed because it had all rights reserved copyright on it.
* Calculates the angle between this and the supplied Vector.
*
* @param v the Vector to calculate the angle to.
* @return the Angle between the two Vectors.
*/
/*public Angle angleBetween(Vector3 v) {
return Angle.fromRadian(Math.acos(Math.min(Math.max(this.normalize().dot(v.normalize()), -1.0d), 1.0d)));
}*/
/**
* Returns a new vector with x value equal to the second parameter, along the line between this vector and the
* passed in vector, or null if not possible.
*
* @param v vector
* @param x x value
* @return intermediate vector
*/
@Nullable
public Vector3 getIntermediateWithXValue(@Nonnull Vector3 v, double x) {
double xDiff = v.x - this.x;
double yDiff = v.y - this.y;
double zDiff = v.z - this.z;
if (xDiff * xDiff < 0.0000001) {
return null;
}
double f = (x - this.x) / xDiff;
if (f < 0 || f > 1) {
return null;
} else {
return new Vector3(this.x + xDiff * f, this.y + yDiff * f, this.z + zDiff * f);
}
}
/**
* Returns a new vector with y value equal to the second parameter, along the line between this vector and the
* passed in vector, or null if not possible.
*
* @param v vector
* @param y y value
* @return intermediate vector
*/
@Nullable
public Vector3 getIntermediateWithYValue(@Nonnull Vector3 v, double y) {
double xDiff = v.x - this.x;
double yDiff = v.y - this.y;
double zDiff = v.z - this.z;
if (yDiff * yDiff < 0.0000001) {
return null;
}
double f = (y - this.y) / yDiff;
if (f < 0 || f > 1) {
return null;
} else {
return new Vector3(this.x + xDiff * f, this.y + yDiff * f, this.z + zDiff * f);
}
}
/**
* Returns a new vector with z value equal to the second parameter, along the line between this vector and the
* passed in vector, or null if not possible.
*
* @param v vector
* @param z z value
* @return intermediate vector
*/
@Nullable
public Vector3 getIntermediateWithZValue(@Nonnull Vector3 v, double z) {
double xDiff = v.x - this.x;
double yDiff = v.y - this.y;
double zDiff = v.z - this.z;
if (zDiff * zDiff < 0.0000001) {
return null;
}
double f = (z - this.z) / zDiff;
if (f < 0 || f > 1) {
return null;
} else {
return new Vector3(this.x + xDiff * f, this.y + yDiff * f, this.z + zDiff * f);
}
}
public Vector3 setComponents(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
return this;
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
@Nonnull
public Vector3 setComponentsAdding(double x, double y, double z, double ax, double ay, double az) {
this.x = x + ax;
this.y = y + ay;
this.z = z + az;
return this;
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
@Nonnull
public Vector3 setComponentsAdding(@Nonnull Vector3 pos, @Nonnull BlockFace face) {
return setComponentsAdding(pos.x, pos.y, pos.z, face.getXOffset(), face.getYOffset(), face.getZOffset());
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
@Nonnull
public Vector3 setComponents(@Nonnull Vector3 pos) {
this.x = pos.x;
this.y = pos.y;
this.z = pos.z;
return this;
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public double getAxis(BlockFace.Axis axis) {
switch (axis) {
case X:
return x;
case Y:
return y;
default:
return z;
}
}
@Override
public String toString() {
return "Vector3(x=" + this.x + ",y=" + this.y + ",z=" + this.z + ")";
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector3)) {
return false;
}
Vector3 other = (Vector3) obj;
return this.x == other.x && this.y == other.y && this.z == other.z;
}
@Override
public int hashCode() {
return ((int) x ^ ((int) z << 12)) ^ ((int) y << 24);
}
public int rawHashCode() {
return super.hashCode();
}
@SneakyThrows
@Override
public Vector3 clone() {
return (Vector3) super.clone();
}
public Vector3f asVector3f() {
return new Vector3f((float) this.x, (float) this.y, (float) this.z);
}
public BlockVector3 asBlockVector3() {
return new BlockVector3(this.getFloorX(), this.getFloorY(), this.getFloorZ());
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy