Refactor vector system to be cleaner

- Move Vector, etc. into `.math` package
- Drop many methods that will be auto-promoted anyways, eg. with
`divide(int)` and `divide(double)` the first is now gone.
- Take Block vectors into their own class hierarchy
- Make it clear throughout the API what takes blockvectors
- many more improvements
This commit is contained in:
Kenzie Togami
2018-10-14 03:40:53 -07:00
parent d7c528247b
commit 399e0ad5fa
230 changed files with 4216 additions and 3913 deletions

View File

@ -0,0 +1,529 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.math;
import com.google.common.collect.ComparisonChain;
import com.sk89q.worldedit.math.transform.AffineTransform;
import java.util.Comparator;
/**
* An immutable 2-dimensional vector.
*/
public final class BlockVector2 {
public static final BlockVector2 ZERO = new BlockVector2(0, 0);
public static final BlockVector2 UNIT_X = new BlockVector2(1, 0);
public static final BlockVector2 UNIT_Z = new BlockVector2(0, 1);
public static final BlockVector2 ONE = new BlockVector2(1, 1);
/**
* A comparator for BlockVector2ds that orders the vectors by rows, with x as the
* column and z as the row.
*
* For example, if x is the horizontal axis and z is the vertical axis, it
* sorts like so:
*
* <pre>
* 0123
* 4567
* 90ab
* cdef
* </pre>
*/
public static final Comparator<BlockVector2> COMPARING_GRID_ARRANGEMENT = (a, b) -> {
return ComparisonChain.start()
.compare(a.getBlockZ(), b.getBlockZ())
.compare(a.getBlockX(), b.getBlockX())
.result();
};
private final int x, z;
/**
* Construct an instance.
*
* @param x the X coordinate
* @param z the Z coordinate
*/
public BlockVector2(double x, double z) {
this((int) Math.floor(x), (int) Math.floor(z));
}
/**
* Construct an instance.
*
* @param x the X coordinate
* @param z the Z coordinate
*/
public BlockVector2(int x, int z) {
this.x = x;
this.z = z;
}
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public int getX() {
return x;
}
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public int getBlockX() {
return x;
}
/**
* Set the X coordinate.
*
* @param x the new X
* @return a new vector
*/
public BlockVector2 withX(int x) {
return new BlockVector2(x, z);
}
/**
* Get the Z coordinate.
*
* @return the z coordinate
*/
public int getZ() {
return z;
}
/**
* Get the Z coordinate.
*
* @return the z coordinate
*/
public int getBlockZ() {
return z;
}
/**
* Set the Z coordinate.
*
* @param z the new Z
* @return a new vector
*/
public BlockVector2 withZ(int z) {
return new BlockVector2(x, z);
}
/**
* Add another vector to this vector and return the result as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public BlockVector2 add(BlockVector2 other) {
return add(other.x, other.z);
}
/**
* Add another vector to this vector and return the result as a new vector.
*
* @param x the value to add
* @param z the value to add
* @return a new vector
*/
public BlockVector2 add(int x, int z) {
return new BlockVector2(this.x + x, this.z + z);
}
/**
* Add a list of vectors to this vector and return the
* result as a new vector.
*
* @param others an array of vectors
* @return a new vector
*/
public BlockVector2 add(BlockVector2... others) {
int newX = x, newZ = z;
for (BlockVector2 other : others) {
newX += other.x;
newZ += other.z;
}
return new BlockVector2(newX, newZ);
}
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public BlockVector2 subtract(BlockVector2 other) {
return subtract(other.x, other.z);
}
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param x the value to subtract
* @param z the value to subtract
* @return a new vector
*/
public BlockVector2 subtract(int x, int z) {
return new BlockVector2(this.x - x, this.z - z);
}
/**
* Subtract a list of vectors from this vector and return the result
* as a new vector.
*
* @param others an array of vectors
* @return a new vector
*/
public BlockVector2 subtract(BlockVector2... others) {
int newX = x, newZ = z;
for (BlockVector2 other : others) {
newX -= other.x;
newZ -= other.z;
}
return new BlockVector2(newX, newZ);
}
/**
* Multiply this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public BlockVector2 multiply(BlockVector2 other) {
return multiply(other.x, other.z);
}
/**
* Multiply this vector by another vector on each component.
*
* @param x the value to multiply
* @param z the value to multiply
* @return a new vector
*/
public BlockVector2 multiply(int x, int z) {
return new BlockVector2(this.x * x, this.z * z);
}
/**
* Multiply this vector by zero or more vectors on each component.
*
* @param others an array of vectors
* @return a new vector
*/
public BlockVector2 multiply(BlockVector2... others) {
int newX = x, newZ = z;
for (BlockVector2 other : others) {
newX *= other.x;
newZ *= other.z;
}
return new BlockVector2(newX, newZ);
}
/**
* Perform scalar multiplication and return a new vector.
*
* @param n the value to multiply
* @return a new vector
*/
public BlockVector2 multiply(int n) {
return multiply(n, n);
}
/**
* Divide this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public BlockVector2 divide(BlockVector2 other) {
return divide(other.x, other.z);
}
/**
* Divide this vector by another vector on each component.
*
* @param x the value to divide by
* @param z the value to divide by
* @return a new vector
*/
public BlockVector2 divide(int x, int z) {
return new BlockVector2(this.x / x, this.z / z);
}
/**
* Perform scalar division and return a new vector.
*
* @param n the value to divide by
* @return a new vector
*/
public BlockVector2 divide(int n) {
return divide(n, n);
}
/**
* Get the length of the vector.
*
* @return length
*/
public double length() {
return Math.sqrt(lengthSq());
}
/**
* Get the length, squared, of the vector.
*
* @return length, squared
*/
public int lengthSq() {
return x * x + z * z;
}
/**
* Get the distance between this vector and another vector.
*
* @param other the other vector
* @return distance
*/
public double distance(BlockVector2 other) {
return Math.sqrt(distanceSq(other));
}
/**
* Get the distance between this vector and another vector, squared.
*
* @param other the other vector
* @return distance
*/
public int distanceSq(BlockVector2 other) {
int dx = other.x - x;
int dz = other.z - z;
return dx * dx + dz * dz;
}
/**
* Get the normalized vector, which is the vector divided by its
* length, as a new vector.
*
* @return a new vector
*/
public BlockVector2 normalize() {
double len = length();
double x = this.x / len;
double z = this.z / len;
return new BlockVector2(x, z);
}
/**
* Gets the dot product of this and another vector.
*
* @param other the other vector
* @return the dot product of this and the other vector
*/
public int dot(BlockVector2 other) {
return x * other.x + z * other.z;
}
/**
* Checks to see if a vector is contained with another.
*
* @param min the minimum point (X, Y, and Z are the lowest)
* @param max the maximum point (X, Y, and Z are the lowest)
* @return true if the vector is contained
*/
public boolean containedWithin(BlockVector2 min, BlockVector2 max) {
return x >= min.x && x <= max.x
&& z >= min.z && z <= max.z;
}
/**
* Floors the values of all components.
*
* @return a new vector
*/
public BlockVector2 floor() {
// already floored, kept for feature parity with Vector2
return this;
}
/**
* Rounds all components up.
*
* @return a new vector
*/
public BlockVector2 ceil() {
// already raised, kept for feature parity with Vector2
return this;
}
/**
* Rounds all components to the closest integer.
*
* <p>Components &lt; 0.5 are rounded down, otherwise up.</p>
*
* @return a new vector
*/
public BlockVector2 round() {
// already rounded, kept for feature parity with Vector2
return this;
}
/**
* Returns a vector with the absolute values of the components of
* this vector.
*
* @return a new vector
*/
public BlockVector2 abs() {
return new BlockVector2(Math.abs(x), Math.abs(z));
}
/**
* Perform a 2D transformation on this vector and return a new one.
*
* @param angle in degrees
* @param aboutX about which x coordinate to rotate
* @param aboutZ about which z coordinate to rotate
* @param translateX what to add after rotation
* @param translateZ what to add after rotation
* @return a new vector
* @see AffineTransform another method to transform vectors
*/
public BlockVector2 transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
angle = Math.toRadians(angle);
double x = this.x - aboutX;
double z = this.z - aboutZ;
double cos = Math.cos(angle);
double sin = Math.sin(angle);
double x2 = x * cos - z * sin;
double z2 = x * sin + z * cos;
return new BlockVector2(
x2 + aboutX + translateX,
z2 + aboutZ + translateZ);
}
/**
* Gets the minimum components of two vectors.
*
* @param v2 the second vector
* @return minimum
*/
public BlockVector2 getMinimum(BlockVector2 v2) {
return new BlockVector2(
Math.min(x, v2.x),
Math.min(z, v2.z)
);
}
/**
* Gets the maximum components of two vectors.
*
* @param v2 the second vector
* @return maximum
*/
public BlockVector2 getMaximum(BlockVector2 v2) {
return new BlockVector2(
Math.max(x, v2.x),
Math.max(z, v2.z)
);
}
public Vector2 toVector2() {
return new Vector2(x, z);
}
/**
* Creates a 3D vector by adding a zero Y component to this vector.
*
* @return a new vector
*/
public Vector3 toVector3() {
return toVector3(0);
}
/**
* Creates a 3D vector by adding the specified Y component to this vector.
*
* @param y the Y component
* @return a new vector
*/
public Vector3 toVector3(double y) {
return new Vector3(x, y, z);
}
/**
* Creates a 3D vector by adding a zero Y component to this vector.
*
* @return a new vector
*/
public BlockVector3 toBlockVector3() {
return toBlockVector3(0);
}
/**
* Creates a 3D vector by adding the specified Y component to this vector.
*
* @param y the Y component
* @return a new vector
*/
public BlockVector3 toBlockVector3(int y) {
return new BlockVector3(x, y, z);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof BlockVector2)) {
return false;
}
BlockVector2 other = (BlockVector2) obj;
return other.x == this.x && other.z == this.z;
}
@Override
public int hashCode() {
int hash = 17;
hash = 31 * hash + Integer.hashCode(x);
hash = 31 * hash + Integer.hashCode(z);
return hash;
}
@Override
public String toString() {
return "(" + x + ", " + z + ")";
}
}

View File

@ -0,0 +1,613 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.math;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.ComparisonChain;
import com.sk89q.worldedit.math.transform.AffineTransform;
import java.util.Comparator;
/**
* An immutable 3-dimensional vector.
*/
public final class BlockVector3 {
public static final BlockVector3 ZERO = new BlockVector3(0, 0, 0);
public static final BlockVector3 UNIT_X = new BlockVector3(1, 0, 0);
public static final BlockVector3 UNIT_Y = new BlockVector3(0, 1, 0);
public static final BlockVector3 UNIT_Z = new BlockVector3(0, 0, 1);
public static final BlockVector3 ONE = new BlockVector3(1, 1, 1);
// thread-safe initialization idiom
private static final class YzxOrderComparator {
private static final Comparator<BlockVector3> YZX_ORDER = (a, b) -> {
return ComparisonChain.start()
.compare(a.y, b.y)
.compare(a.z, b.z)
.compare(a.x, b.x)
.result();
};
}
/**
* Returns a comparator that sorts vectors first by Y, then Z, then X.
*
* <p>
* Useful for sorting by chunk block storage order.
*/
public static Comparator<BlockVector3> sortByCoordsYzx() {
return YzxOrderComparator.YZX_ORDER;
}
private final int x, y, z;
/**
* Construct an instance.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
public BlockVector3(double x, double y, double z) {
this((int) Math.floor(x), (int) Math.floor(y), (int) Math.floor(z));
}
/**
* Construct an instance.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
public BlockVector3(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public int getX() {
return x;
}
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public int getBlockX() {
return x;
}
/**
* Set the X coordinate.
*
* @param x the new X
* @return a new vector
*/
public BlockVector3 withX(int x) {
return new BlockVector3(x, y, z);
}
/**
* Get the Y coordinate.
*
* @return the y coordinate
*/
public int getY() {
return y;
}
/**
* Get the Y coordinate.
*
* @return the y coordinate
*/
public int getBlockY() {
return y;
}
/**
* Set the Y coordinate.
*
* @param y the new Y
* @return a new vector
*/
public BlockVector3 withY(int y) {
return new BlockVector3(x, y, z);
}
/**
* Get the Z coordinate.
*
* @return the z coordinate
*/
public int getZ() {
return z;
}
/**
* Get the Z coordinate.
*
* @return the z coordinate
*/
public int getBlockZ() {
return z;
}
/**
* Set the Z coordinate.
*
* @param z the new Z
* @return a new vector
*/
public BlockVector3 withZ(int z) {
return new BlockVector3(x, y, z);
}
/**
* Add another vector to this vector and return the result as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public BlockVector3 add(BlockVector3 other) {
return add(other.x, other.y, other.z);
}
/**
* Add another vector to this vector and return the result as a new vector.
*
* @param x the value to add
* @param y the value to add
* @param z the value to add
* @return a new vector
*/
public BlockVector3 add(int x, int y, int z) {
return new BlockVector3(this.x + x, this.y + y, this.z + z);
}
/**
* Add a list of vectors to this vector and return the
* result as a new vector.
*
* @param others an array of vectors
* @return a new vector
*/
public BlockVector3 add(BlockVector3... others) {
int newX = x, newY = y, newZ = z;
for (BlockVector3 other : others) {
newX += other.x;
newY += other.y;
newZ += other.z;
}
return new BlockVector3(newX, newY, newZ);
}
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public BlockVector3 subtract(BlockVector3 other) {
return subtract(other.x, other.y, other.z);
}
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param x the value to subtract
* @param y the value to subtract
* @param z the value to subtract
* @return a new vector
*/
public BlockVector3 subtract(int x, int y, int z) {
return new BlockVector3(this.x - x, this.y - y, this.z - z);
}
/**
* Subtract a list of vectors from this vector and return the result
* as a new vector.
*
* @param others an array of vectors
* @return a new vector
*/
public BlockVector3 subtract(BlockVector3... others) {
int newX = x, newY = y, newZ = z;
for (BlockVector3 other : others) {
newX -= other.x;
newY -= other.y;
newZ -= other.z;
}
return new BlockVector3(newX, newY, newZ);
}
/**
* Multiply this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public BlockVector3 multiply(BlockVector3 other) {
return multiply(other.x, other.y, other.z);
}
/**
* Multiply this vector by another vector on each component.
*
* @param x the value to multiply
* @param y the value to multiply
* @param z the value to multiply
* @return a new vector
*/
public BlockVector3 multiply(int x, int y, int z) {
return new BlockVector3(this.x * x, this.y * y, this.z * z);
}
/**
* Multiply this vector by zero or more vectors on each component.
*
* @param others an array of vectors
* @return a new vector
*/
public BlockVector3 multiply(BlockVector3... others) {
int newX = x, newY = y, newZ = z;
for (BlockVector3 other : others) {
newX *= other.x;
newY *= other.y;
newZ *= other.z;
}
return new BlockVector3(newX, newY, newZ);
}
/**
* Perform scalar multiplication and return a new vector.
*
* @param n the value to multiply
* @return a new vector
*/
public BlockVector3 multiply(int n) {
return multiply(n, n, n);
}
/**
* Divide this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public BlockVector3 divide(BlockVector3 other) {
return divide(other.x, other.y, other.z);
}
/**
* Divide this vector by another vector on each component.
*
* @param x the value to divide by
* @param y the value to divide by
* @param z the value to divide by
* @return a new vector
*/
public BlockVector3 divide(int x, int y, int z) {
return new BlockVector3(this.x / x, this.y / y, this.z / z);
}
/**
* Perform scalar division and return a new vector.
*
* @param n the value to divide by
* @return a new vector
*/
public BlockVector3 divide(int n) {
return divide(n, n, n);
}
/**
* Get the length of the vector.
*
* @return length
*/
public double length() {
return Math.sqrt(lengthSq());
}
/**
* Get the length, squared, of the vector.
*
* @return length, squared
*/
public int lengthSq() {
return x * x + y * y + z * z;
}
/**
* Get the distance between this vector and another vector.
*
* @param other the other vector
* @return distance
*/
public double distance(BlockVector3 other) {
return Math.sqrt(distanceSq(other));
}
/**
* Get the distance between this vector and another vector, squared.
*
* @param other the other vector
* @return distance
*/
public int distanceSq(BlockVector3 other) {
int dx = other.x - x;
int dy = other.y - y;
int dz = other.z - z;
return dx * dx + dy * dy + dz * dz;
}
/**
* Get the normalized vector, which is the vector divided by its
* length, as a new vector.
*
* @return a new vector
*/
public BlockVector3 normalize() {
double len = length();
double x = this.x / len;
double y = this.y / len;
double z = this.z / len;
return new BlockVector3(x, y, z);
}
/**
* Gets the dot product of this and another vector.
*
* @param other the other vector
* @return the dot product of this and the other vector
*/
public double dot(BlockVector3 other) {
return x * other.x + y * other.y + z * other.z;
}
/**
* Gets the cross product of this and another vector.
*
* @param other the other vector
* @return the cross product of this and the other vector
*/
public BlockVector3 cross(BlockVector3 other) {
return new BlockVector3(
y * other.z - z * other.y,
z * other.x - x * other.z,
x * other.y - y * other.x
);
}
/**
* Checks to see if a vector is contained with another.
*
* @param min the minimum point (X, Y, and Z are the lowest)
* @param max the maximum point (X, Y, and Z are the lowest)
* @return true if the vector is contained
*/
public boolean containedWithin(BlockVector3 min, BlockVector3 max) {
return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z;
}
/**
* Clamp the Y component.
*
* @param min the minimum value
* @param max the maximum value
* @return a new vector
*/
public BlockVector3 clampY(int min, int max) {
checkArgument(min <= max, "minimum cannot be greater than maximum");
if (y < min) {
return new BlockVector3(x, min, z);
}
if (y > max) {
return new BlockVector3(x, max, z);
}
return this;
}
/**
* Floors the values of all components.
*
* @return a new vector
*/
public BlockVector3 floor() {
// already floored, kept for feature parity with Vector3
return this;
}
/**
* Rounds all components up.
*
* @return a new vector
*/
public BlockVector3 ceil() {
// already raised, kept for feature parity with Vector3
return this;
}
/**
* Rounds all components to the closest integer.
*
* <p>Components &lt; 0.5 are rounded down, otherwise up.</p>
*
* @return a new vector
*/
public BlockVector3 round() {
// already rounded, kept for feature parity with Vector3
return this;
}
/**
* Returns a vector with the absolute values of the components of
* this vector.
*
* @return a new vector
*/
public BlockVector3 abs() {
return new BlockVector3(Math.abs(x), Math.abs(y), Math.abs(z));
}
/**
* Perform a 2D transformation on this vector and return a new one.
*
* @param angle in degrees
* @param aboutX about which x coordinate to rotate
* @param aboutZ about which z coordinate to rotate
* @param translateX what to add after rotation
* @param translateZ what to add after rotation
* @return a new vector
* @see AffineTransform another method to transform vectors
*/
public BlockVector3 transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
angle = Math.toRadians(angle);
double x = this.x - aboutX;
double z = this.z - aboutZ;
double cos = Math.cos(angle);
double sin = Math.sin(angle);
double x2 = x * cos - z * sin;
double z2 = x * sin + z * cos;
return new BlockVector3(
x2 + aboutX + translateX,
y,
z2 + aboutZ + translateZ
);
}
/**
* Get this vector's pitch as used within the game.
*
* @return pitch in radians
*/
public double toPitch() {
double x = getX();
double z = getZ();
if (x == 0 && z == 0) {
return getY() > 0 ? -90 : 90;
} else {
double x2 = x * x;
double z2 = z * z;
double xz = Math.sqrt(x2 + z2);
return Math.toDegrees(Math.atan(-getY() / xz));
}
}
/**
* Get this vector's yaw as used within the game.
*
* @return yaw in radians
*/
public double toYaw() {
double x = getX();
double z = getZ();
double t = Math.atan2(-x, z);
double tau = 2 * Math.PI;
return Math.toDegrees(((t + tau) % tau));
}
/**
* Gets the minimum components of two vectors.
*
* @param v2 the second vector
* @return minimum
*/
public BlockVector3 getMinimum(BlockVector3 v2) {
return new BlockVector3(
Math.min(x, v2.x),
Math.min(y, v2.y),
Math.min(z, v2.z)
);
}
/**
* Gets the maximum components of two vectors.
*
* @param v2 the second vector
* @return maximum
*/
public BlockVector3 getMaximum(BlockVector3 v2) {
return new BlockVector3(
Math.max(x, v2.x),
Math.max(y, v2.y),
Math.max(z, v2.z)
);
}
/**
* Creates a 2D vector by dropping the Y component from this vector.
*
* @return a new {@link BlockVector2}
*/
public BlockVector2 toBlockVector2() {
return new BlockVector2(x, z);
}
public Vector3 toVector3() {
return new Vector3(x, y, z);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof BlockVector3)) {
return false;
}
BlockVector3 other = (BlockVector3) obj;
return other.x == this.x && other.y == this.y && other.z == this.z;
}
@Override
public int hashCode() {
int hash = 17;
hash = 31 * hash + Integer.hashCode(x);
hash = 31 * hash + Integer.hashCode(y);
hash = 31 * hash + Integer.hashCode(z);
return hash;
}
@Override
public String toString() {
return "(" + x + ", " + y + ", " + z + ")";
}
}

View File

@ -0,0 +1,471 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.math;
import com.sk89q.worldedit.math.transform.AffineTransform;
/**
* An immutable 2-dimensional vector.
*/
public final class Vector2 {
public static final Vector2 ZERO = new Vector2(0, 0);
public static final Vector2 UNIT_X = new Vector2(1, 0);
public static final Vector2 UNIT_Z = new Vector2(0, 1);
public static final Vector2 ONE = new Vector2(1, 1);
private final double x, z;
/**
* Construct an instance.
*
* @param x the X coordinate
* @param z the Z coordinate
*/
public Vector2(double x, double z) {
this.x = x;
this.z = z;
}
/**
* Copy another vector.
*
* @param other the other vector
*/
public Vector2(Vector2 other) {
this.x = other.x;
this.z = other.z;
}
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public double getX() {
return x;
}
/**
* Set the X coordinate.
*
* @param x the new X
* @return a new vector
*/
public Vector2 withX(double x) {
return new Vector2(x, z);
}
/**
* Get the Z coordinate.
*
* @return the z coordinate
*/
public double getZ() {
return z;
}
/**
* Set the Z coordinate.
*
* @param z the new Z
* @return a new vector
*/
public Vector2 withZ(double z) {
return new Vector2(x, z);
}
/**
* Add another vector to this vector and return the result as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public Vector2 add(Vector2 other) {
return add(other.x, other.z);
}
/**
* Add another vector to this vector and return the result as a new vector.
*
* @param x the value to add
* @param z the value to add
* @return a new vector
*/
public Vector2 add(double x, double z) {
return new Vector2(this.x + x, this.z + z);
}
/**
* Add a list of vectors to this vector and return the
* result as a new vector.
*
* @param others an array of vectors
* @return a new vector
*/
public Vector2 add(Vector2... others) {
double newX = x, newZ = z;
for (Vector2 other : others) {
newX += other.x;
newZ += other.z;
}
return new Vector2(newX, newZ);
}
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public Vector2 subtract(Vector2 other) {
return subtract(other.x, other.z);
}
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param x the value to subtract
* @param z the value to subtract
* @return a new vector
*/
public Vector2 subtract(double x, double z) {
return new Vector2(this.x - x, this.z - z);
}
/**
* Subtract a list of vectors from this vector and return the result
* as a new vector.
*
* @param others an array of vectors
* @return a new vector
*/
public Vector2 subtract(Vector2... others) {
double newX = x, newZ = z;
for (Vector2 other : others) {
newX -= other.x;
newZ -= other.z;
}
return new Vector2(newX, newZ);
}
/**
* Multiply this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public Vector2 multiply(Vector2 other) {
return multiply(other.x, other.z);
}
/**
* Multiply this vector by another vector on each component.
*
* @param x the value to multiply
* @param z the value to multiply
* @return a new vector
*/
public Vector2 multiply(double x, double z) {
return new Vector2(this.x * x, this.z * z);
}
/**
* Multiply this vector by zero or more vectors on each component.
*
* @param others an array of vectors
* @return a new vector
*/
public Vector2 multiply(Vector2... others) {
double newX = x, newZ = z;
for (Vector2 other : others) {
newX *= other.x;
newZ *= other.z;
}
return new Vector2(newX, newZ);
}
/**
* Perform scalar multiplication and return a new vector.
*
* @param n the value to multiply
* @return a new vector
*/
public Vector2 multiply(double n) {
return multiply(n, n);
}
/**
* Divide this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public Vector2 divide(Vector2 other) {
return divide(other.x, other.z);
}
/**
* Divide this vector by another vector on each component.
*
* @param x the value to divide by
* @param z the value to divide by
* @return a new vector
*/
public Vector2 divide(double x, double z) {
return new Vector2(this.x / x, this.z / z);
}
/**
* Perform scalar division and return a new vector.
*
* @param n the value to divide by
* @return a new vector
*/
public Vector2 divide(double n) {
return divide(n, n);
}
/**
* Get the length of the vector.
*
* @return length
*/
public double length() {
return Math.sqrt(lengthSq());
}
/**
* Get the length, squared, of the vector.
*
* @return length, squared
*/
public double lengthSq() {
return x * x + z * z;
}
/**
* Get the distance between this vector and another vector.
*
* @param other the other vector
* @return distance
*/
public double distance(Vector2 other) {
return Math.sqrt(distanceSq(other));
}
/**
* Get the distance between this vector and another vector, squared.
*
* @param other the other vector
* @return distance
*/
public double distanceSq(Vector2 other) {
double dx = other.x - x;
double dz = other.z - z;
return dx * dx + dz * dz;
}
/**
* Get the normalized vector, which is the vector divided by its
* length, as a new vector.
*
* @return a new vector
*/
public Vector2 normalize() {
return divide(length());
}
/**
* Gets the dot product of this and another vector.
*
* @param other the other vector
* @return the dot product of this and the other vector
*/
public double dot(Vector2 other) {
return x * other.x + z * other.z;
}
/**
* Checks to see if a vector is contained with another.
*
* @param min the minimum point (X, Y, and Z are the lowest)
* @param max the maximum point (X, Y, and Z are the lowest)
* @return true if the vector is contained
*/
public boolean containedWithin(Vector2 min, Vector2 max) {
return x >= min.x && x <= max.x
&& z >= min.z && z <= max.z;
}
/**
* Floors the values of all components.
*
* @return a new vector
*/
public Vector2 floor() {
return new Vector2(Math.floor(x), Math.floor(z));
}
/**
* Rounds all components up.
*
* @return a new vector
*/
public Vector2 ceil() {
return new Vector2(Math.ceil(x), Math.ceil(z));
}
/**
* Rounds all components to the closest integer.
*
* <p>Components &lt; 0.5 are rounded down, otherwise up.</p>
*
* @return a new vector
*/
public Vector2 round() {
return new Vector2(Math.floor(x + 0.5), Math.floor(z + 0.5));
}
/**
* Returns a vector with the absolute values of the components of
* this vector.
*
* @return a new vector
*/
public Vector2 abs() {
return new Vector2(Math.abs(x), Math.abs(z));
}
/**
* Perform a 2D transformation on this vector and return a new one.
*
* @param angle in degrees
* @param aboutX about which x coordinate to rotate
* @param aboutZ about which z coordinate to rotate
* @param translateX what to add after rotation
* @param translateZ what to add after rotation
* @return a new vector
* @see AffineTransform another method to transform vectors
*/
public Vector2 transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
angle = Math.toRadians(angle);
double x = this.x - aboutX;
double z = this.z - aboutZ;
double cos = Math.cos(angle);
double sin = Math.sin(angle);
double x2 = x * cos - z * sin;
double z2 = x * sin + z * cos;
return new Vector2(
x2 + aboutX + translateX,
z2 + aboutZ + translateZ);
}
/**
* Gets the minimum components of two vectors.
*
* @param v2 the second vector
* @return minimum
*/
public Vector2 getMinimum(Vector2 v2) {
return new Vector2(
Math.min(x, v2.x),
Math.min(z, v2.z)
);
}
/**
* Gets the maximum components of two vectors.
*
* @param v2 the second vector
* @return maximum
*/
public Vector2 getMaximum(Vector2 v2) {
return new Vector2(
Math.max(x, v2.x),
Math.max(z, v2.z)
);
}
public static BlockVector2 toBlockPoint(double x, double z) {
return new BlockVector2(x, z);
}
/**
* Create a new {@link BlockVector2} from this vector.
*
* @return a new {@link BlockVector2}
*/
public BlockVector2 toBlockPoint() {
return toBlockPoint(x, z);
}
/**
* Creates a 3D vector by adding a zero Y component to this vector.
*
* @return a new vector
*/
public Vector3 toVector3() {
return toVector3(0);
}
/**
* Creates a 3D vector by adding the specified Y component to this vector.
*
* @param y the Y component
* @return a new vector
*/
public Vector3 toVector3(double y) {
return new Vector3(x, y, z);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector2)) {
return false;
}
Vector2 other = (Vector2) obj;
return other.x == this.x && other.z == this.z;
}
@Override
public int hashCode() {
int hash = 17;
hash = 31 * hash + Double.hashCode(x);
hash = 31 * hash + Double.hashCode(z);
return hash;
}
@Override
public String toString() {
return "(" + x + ", " + z + ")";
}
}

View File

@ -0,0 +1,596 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.math;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.ComparisonChain;
import com.sk89q.worldedit.math.transform.AffineTransform;
import java.util.Comparator;
/**
* An immutable 3-dimensional vector.
*/
public final class Vector3 {
public static final Vector3 ZERO = new Vector3(0, 0, 0);
public static final Vector3 UNIT_X = new Vector3(1, 0, 0);
public static final Vector3 UNIT_Y = new Vector3(0, 1, 0);
public static final Vector3 UNIT_Z = new Vector3(0, 0, 1);
public static final Vector3 ONE = new Vector3(1, 1, 1);
// thread-safe initialization idiom
private static final class YzxOrderComparator {
private static final Comparator<Vector3> YZX_ORDER = (a, b) -> {
return ComparisonChain.start()
.compare(a.y, b.y)
.compare(a.z, b.z)
.compare(a.x, b.x)
.result();
};
}
/**
* Returns a comparator that sorts vectors first by Y, then Z, then X.
*
* <p>
* Useful for sorting by chunk block storage order.
*/
public static Comparator<Vector3> sortByCoordsYzx() {
return YzxOrderComparator.YZX_ORDER;
}
private final double x, y, z;
/**
* Construct an instance.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
public Vector3(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* Copy another vector.
*
* @param other another vector to make a copy of
*/
public Vector3(Vector3 other) {
this.x = other.x;
this.y = other.y;
this.z = other.z;
}
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public double getX() {
return x;
}
/**
* Set the X coordinate.
*
* @param x the new X
* @return a new vector
*/
public Vector3 withX(double x) {
return new Vector3(x, y, z);
}
/**
* Get the Y coordinate.
*
* @return the y coordinate
*/
public double getY() {
return y;
}
/**
* Set the Y coordinate.
*
* @param y the new Y
* @return a new vector
*/
public Vector3 withY(double y) {
return new Vector3(x, y, z);
}
/**
* Get the Z coordinate.
*
* @return the z coordinate
*/
public double getZ() {
return z;
}
/**
* Set the Z coordinate.
*
* @param z the new Z
* @return a new vector
*/
public Vector3 withZ(double z) {
return new Vector3(x, y, z);
}
/**
* Add another vector to this vector and return the result as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public Vector3 add(Vector3 other) {
return add(other.x, other.y, other.z);
}
/**
* Add another vector to this vector and return the result as a new vector.
*
* @param x the value to add
* @param y the value to add
* @param z the value to add
* @return a new vector
*/
public Vector3 add(double x, double y, double z) {
return new Vector3(this.x + x, this.y + y, this.z + z);
}
/**
* Add a list of vectors to this vector and return the
* result as a new vector.
*
* @param others an array of vectors
* @return a new vector
*/
public Vector3 add(Vector3... others) {
double newX = x, newY = y, newZ = z;
for (Vector3 other : others) {
newX += other.x;
newY += other.y;
newZ += other.z;
}
return new Vector3(newX, newY, newZ);
}
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public Vector3 subtract(Vector3 other) {
return subtract(other.x, other.y, other.z);
}
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param x the value to subtract
* @param y the value to subtract
* @param z the value to subtract
* @return a new vector
*/
public Vector3 subtract(double x, double y, double z) {
return new Vector3(this.x - x, this.y - y, this.z - z);
}
/**
* Subtract a list of vectors from this vector and return the result
* as a new vector.
*
* @param others an array of vectors
* @return a new vector
*/
public Vector3 subtract(Vector3... others) {
double newX = x, newY = y, newZ = z;
for (Vector3 other : others) {
newX -= other.x;
newY -= other.y;
newZ -= other.z;
}
return new Vector3(newX, newY, newZ);
}
/**
* Multiply this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public Vector3 multiply(Vector3 other) {
return multiply(other.x, other.y, other.z);
}
/**
* Multiply this vector by another vector on each component.
*
* @param x the value to multiply
* @param y the value to multiply
* @param z the value to multiply
* @return a new vector
*/
public Vector3 multiply(double x, double y, double z) {
return new Vector3(this.x * x, this.y * y, this.z * z);
}
/**
* Multiply this vector by zero or more vectors on each component.
*
* @param others an array of vectors
* @return a new vector
*/
public Vector3 multiply(Vector3... others) {
double newX = x, newY = y, newZ = z;
for (Vector3 other : others) {
newX *= other.x;
newY *= other.y;
newZ *= other.z;
}
return new Vector3(newX, newY, newZ);
}
/**
* Perform scalar multiplication and return a new vector.
*
* @param n the value to multiply
* @return a new vector
*/
public Vector3 multiply(double n) {
return multiply(n, n, n);
}
/**
* Divide this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public Vector3 divide(Vector3 other) {
return divide(other.x, other.y, other.z);
}
/**
* Divide this vector by another vector on each component.
*
* @param x the value to divide by
* @param y the value to divide by
* @param z the value to divide by
* @return a new vector
*/
public Vector3 divide(double x, double y, double z) {
return new Vector3(this.x / x, this.y / y, this.z / z);
}
/**
* Perform scalar division and return a new vector.
*
* @param n the value to divide by
* @return a new vector
*/
public Vector3 divide(double n) {
return divide(n, n, n);
}
/**
* Get the length of the vector.
*
* @return length
*/
public double length() {
return Math.sqrt(lengthSq());
}
/**
* Get the length, squared, of the vector.
*
* @return length, squared
*/
public double lengthSq() {
return x * x + y * y + z * z;
}
/**
* Get the distance between this vector and another vector.
*
* @param other the other vector
* @return distance
*/
public double distance(Vector3 other) {
return Math.sqrt(distanceSq(other));
}
/**
* Get the distance between this vector and another vector, squared.
*
* @param other the other vector
* @return distance
*/
public double distanceSq(Vector3 other) {
double dx = other.x - x;
double dy = other.y - y;
double dz = other.z - z;
return dx * dx + dy * dy + dz * dz;
}
/**
* Get the normalized vector, which is the vector divided by its
* length, as a new vector.
*
* @return a new vector
*/
public Vector3 normalize() {
return divide(length());
}
/**
* Gets the dot product of this and another vector.
*
* @param other the other vector
* @return the dot product of this and the other vector
*/
public double dot(Vector3 other) {
return x * other.x + y * other.y + z * other.z;
}
/**
* Gets the cross product of this and another vector.
*
* @param other the other vector
* @return the cross product of this and the other vector
*/
public Vector3 cross(Vector3 other) {
return new Vector3(
y * other.z - z * other.y,
z * other.x - x * other.z,
x * other.y - y * other.x
);
}
/**
* Checks to see if a vector is contained with another.
*
* @param min the minimum point (X, Y, and Z are the lowest)
* @param max the maximum point (X, Y, and Z are the lowest)
* @return true if the vector is contained
*/
public boolean containedWithin(Vector3 min, Vector3 max) {
return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z;
}
/**
* Clamp the Y component.
*
* @param min the minimum value
* @param max the maximum value
* @return a new vector
*/
public Vector3 clampY(int min, int max) {
checkArgument(min <= max, "minimum cannot be greater than maximum");
if (y < min) {
return new Vector3(x, min, z);
}
if (y > max) {
return new Vector3(x, max, z);
}
return this;
}
/**
* Floors the values of all components.
*
* @return a new vector
*/
public Vector3 floor() {
return new Vector3(Math.floor(x), Math.floor(y), Math.floor(z));
}
/**
* Rounds all components up.
*
* @return a new vector
*/
public Vector3 ceil() {
return new Vector3(Math.ceil(x), Math.ceil(y), Math.ceil(z));
}
/**
* Rounds all components to the closest integer.
*
* <p>Components &lt; 0.5 are rounded down, otherwise up.</p>
*
* @return a new vector
*/
public Vector3 round() {
return new Vector3(Math.floor(x + 0.5), Math.floor(y + 0.5), Math.floor(z + 0.5));
}
/**
* Returns a vector with the absolute values of the components of
* this vector.
*
* @return a new vector
*/
public Vector3 abs() {
return new Vector3(Math.abs(x), Math.abs(y), Math.abs(z));
}
/**
* Perform a 2D transformation on this vector and return a new one.
*
* @param angle in degrees
* @param aboutX about which x coordinate to rotate
* @param aboutZ about which z coordinate to rotate
* @param translateX what to add after rotation
* @param translateZ what to add after rotation
* @return a new vector
* @see AffineTransform another method to transform vectors
*/
public Vector3 transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
angle = Math.toRadians(angle);
double x = this.x - aboutX;
double z = this.z - aboutZ;
double cos = Math.cos(angle);
double sin = Math.sin(angle);
double x2 = x * cos - z * sin;
double z2 = x * sin + z * cos;
return new Vector3(
x2 + aboutX + translateX,
y,
z2 + aboutZ + translateZ
);
}
/**
* Get this vector's pitch as used within the game.
*
* @return pitch in radians
*/
public double toPitch() {
double x = getX();
double z = getZ();
if (x == 0 && z == 0) {
return getY() > 0 ? -90 : 90;
} else {
double x2 = x * x;
double z2 = z * z;
double xz = Math.sqrt(x2 + z2);
return Math.toDegrees(Math.atan(-getY() / xz));
}
}
/**
* Get this vector's yaw as used within the game.
*
* @return yaw in radians
*/
public double toYaw() {
double x = getX();
double z = getZ();
double t = Math.atan2(-x, z);
double tau = 2 * Math.PI;
return Math.toDegrees(((t + tau) % tau));
}
/**
* Gets the minimum components of two vectors.
*
* @param v2 the second vector
* @return minimum
*/
public Vector3 getMinimum(Vector3 v2) {
return new Vector3(
Math.min(x, v2.x),
Math.min(y, v2.y),
Math.min(z, v2.z)
);
}
/**
* Gets the maximum components of two vectors.
*
* @param v2 the second vector
* @return maximum
*/
public Vector3 getMaximum(Vector3 v2) {
return new Vector3(
Math.max(x, v2.x),
Math.max(y, v2.y),
Math.max(z, v2.z)
);
}
/**
* Create a new {@code BlockVector} using the given components.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
* @return a new {@code BlockVector}
*/
public static BlockVector3 toBlockPoint(double x, double y, double z) {
return new BlockVector3(x, y, z);
}
/**
* Create a new {@code BlockVector} from this vector.
*
* @return a new {@code BlockVector}
*/
public BlockVector3 toBlockPoint() {
return toBlockPoint(x, y, z);
}
/**
* Creates a 2D vector by dropping the Y component from this vector.
*
* @return a new {@link Vector2}
*/
public Vector2 toVector2() {
return new Vector2(x, z);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector3)) {
return false;
}
Vector3 other = (Vector3) obj;
return other.x == this.x && other.y == this.y && other.z == this.z;
}
@Override
public int hashCode() {
int hash = 17;
hash = 31 * hash + Double.hashCode(x);
hash = 31 * hash + Double.hashCode(y);
hash = 31 * hash + Double.hashCode(z);
return hash;
}
@Override
public String toString() {
return "(" + x + ", " + y + ", " + z + ")";
}
}

View File

@ -23,7 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -105,7 +105,7 @@ public class HeightMap {
public int apply(int[] data) throws MaxChangedBlocksException {
checkNotNull(data);
Vector minY = region.getMinimumPoint();
BlockVector3 minY = region.getMinimumPoint();
int originX = minY.getBlockX();
int originY = minY.getBlockY();
int originZ = minY.getBlockZ();
@ -134,17 +134,17 @@ public class HeightMap {
// Depending on growing or shrinking we need to start at the bottom or top
if (newHeight > curHeight) {
// Set the top block of the column to be the same type (this might go wrong with rounding)
BlockState existing = session.getBlock(new Vector(xr, curHeight, zr));
BlockState existing = session.getBlock(new BlockVector3(xr, curHeight, zr));
// Skip water/lava
if (existing.getBlockType() != BlockTypes.WATER && existing.getBlockType() != BlockTypes.LAVA) {
session.setBlock(new Vector(xr, newHeight, zr), existing);
session.setBlock(new BlockVector3(xr, newHeight, zr), existing);
++blocksChanged;
// Grow -- start from 1 below top replacing airblocks
for (int y = newHeight - 1 - originY; y >= 0; --y) {
int copyFrom = (int) (y * scale);
session.setBlock(new Vector(xr, originY + y, zr), session.getBlock(new Vector(xr, originY + copyFrom, zr)));
session.setBlock(new BlockVector3(xr, originY + y, zr), session.getBlock(new BlockVector3(xr, originY + copyFrom, zr)));
++blocksChanged;
}
}
@ -152,18 +152,18 @@ public class HeightMap {
// Shrink -- start from bottom
for (int y = 0; y < newHeight - originY; ++y) {
int copyFrom = (int) (y * scale);
session.setBlock(new Vector(xr, originY + y, zr), session.getBlock(new Vector(xr, originY + copyFrom, zr)));
session.setBlock(new BlockVector3(xr, originY + y, zr), session.getBlock(new BlockVector3(xr, originY + copyFrom, zr)));
++blocksChanged;
}
// Set the top block of the column to be the same type
// (this could otherwise go wrong with rounding)
session.setBlock(new Vector(xr, newHeight, zr), session.getBlock(new Vector(xr, curHeight, zr)));
session.setBlock(new BlockVector3(xr, newHeight, zr), session.getBlock(new BlockVector3(xr, curHeight, zr)));
++blocksChanged;
// Fill rest with air
for (int y = newHeight + 1; y <= curHeight; ++y) {
session.setBlock(new Vector(xr, y, zr), fillerAir);
session.setBlock(new BlockVector3(xr, y, zr), fillerAir);
++blocksChanged;
}
}

View File

@ -19,8 +19,8 @@
package com.sk89q.worldedit.math.geom;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.Vector2;
import java.util.ArrayList;
import java.util.List;
@ -40,9 +40,9 @@ public final class Polygons {
* @param center the center point of the cylinder
* @param radius the radius of the cylinder
* @param maxPoints max points to be used for the calculation
* @return a list of {@link BlockVector2D} which resemble the shape as a polygon
* @return a list of {@link BlockVector2} which resemble the shape as a polygon
*/
public static List<BlockVector2D> polygonizeCylinder(Vector2D center, Vector2D radius, int maxPoints) {
public static List<BlockVector2> polygonizeCylinder(BlockVector2 center, Vector2 radius, int maxPoints) {
int nPoints = (int) Math.ceil(Math.PI*radius.length());
// These strange semantics for maxPoints are copied from the selectSecondary method.
@ -50,11 +50,11 @@ public final class Polygons {
nPoints = maxPoints - 1;
}
final List<BlockVector2D> points = new ArrayList<>(nPoints);
final List<BlockVector2> points = new ArrayList<>(nPoints);
for (int i = 0; i < nPoints; ++i) {
double angle = i * (2.0 * Math.PI) / nPoints;
final Vector2D pos = new Vector2D(Math.cos(angle), Math.sin(angle));
final BlockVector2D blockVector2D = pos.multiply(radius).add(center).toBlockVector2D();
final Vector2 pos = new Vector2(Math.cos(angle), Math.sin(angle));
final BlockVector2 blockVector2D = pos.multiply(radius).toBlockPoint().add(center);
points.add(blockVector2D);
}

View File

@ -21,7 +21,7 @@
package com.sk89q.worldedit.math.interpolation;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.Vector3;
import java.util.List;
@ -44,7 +44,7 @@ public interface Interpolation {
* @param position the position to interpolate
* @return the result
*/
Vector getPosition(double position);
Vector3 getPosition(double position);
/**
* Gets the result of f'(position).
@ -52,7 +52,7 @@ public interface Interpolation {
* @param position the position to interpolate
* @return the result
*/
Vector get1stDerivative(double position);
Vector3 get1stDerivative(double position);
/**
* Gets the result of &int;<sub>a</sub><sup style="position: relative; left: -1ex">b</sup>|f'(t)| dt.<br />

View File

@ -23,7 +23,7 @@ package com.sk89q.worldedit.math.interpolation;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.Vector3;
import java.util.Collections;
import java.util.List;
@ -37,10 +37,10 @@ import java.util.List;
public class KochanekBartelsInterpolation implements Interpolation {
private List<Node> nodes;
private Vector[] coeffA;
private Vector[] coeffB;
private Vector[] coeffC;
private Vector[] coeffD;
private Vector3[] coeffA;
private Vector3[] coeffB;
private Vector3[] coeffC;
private Vector3[] coeffD;
private double scaling;
public KochanekBartelsInterpolation() {
@ -57,10 +57,10 @@ public class KochanekBartelsInterpolation implements Interpolation {
private void recalc() {
final int nNodes = nodes.size();
coeffA = new Vector[nNodes];
coeffB = new Vector[nNodes];
coeffC = new Vector[nNodes];
coeffD = new Vector[nNodes];
coeffA = new Vector3[nNodes];
coeffB = new Vector3[nNodes];
coeffC = new Vector3[nNodes];
coeffD = new Vector3[nNodes];
if (nNodes == 0)
return;
@ -107,11 +107,11 @@ public class KochanekBartelsInterpolation implements Interpolation {
* @param f4 coefficient for baseIndex+2
* @return linear combination of nodes[n-1..n+2] with f1..4
*/
private Vector linearCombination(int baseIndex, double f1, double f2, double f3, double f4) {
final Vector r1 = retrieve(baseIndex - 1).multiply(f1);
final Vector r2 = retrieve(baseIndex ).multiply(f2);
final Vector r3 = retrieve(baseIndex + 1).multiply(f3);
final Vector r4 = retrieve(baseIndex + 2).multiply(f4);
private Vector3 linearCombination(int baseIndex, double f1, double f2, double f3, double f4) {
final Vector3 r1 = retrieve(baseIndex - 1).multiply(f1);
final Vector3 r2 = retrieve(baseIndex ).multiply(f2);
final Vector3 r3 = retrieve(baseIndex + 1).multiply(f3);
final Vector3 r4 = retrieve(baseIndex + 2).multiply(f4);
return r1.add(r2).add(r3).add(r4);
}
@ -122,7 +122,7 @@ public class KochanekBartelsInterpolation implements Interpolation {
* @param index node index to retrieve
* @return nodes[clamp(0, nodes.length-1)]
*/
private Vector retrieve(int index) {
private Vector3 retrieve(int index) {
if (index < 0)
return fastRetrieve(0);
@ -132,12 +132,12 @@ public class KochanekBartelsInterpolation implements Interpolation {
return fastRetrieve(index);
}
private Vector fastRetrieve(int index) {
private Vector3 fastRetrieve(int index) {
return nodes.get(index).getPosition();
}
@Override
public Vector getPosition(double position) {
public Vector3 getPosition(double position) {
if (coeffA == null)
throw new IllegalStateException("Must call setNodes first.");
@ -149,16 +149,16 @@ public class KochanekBartelsInterpolation implements Interpolation {
final int index = (int) Math.floor(position);
final double remainder = position - index;
final Vector a = coeffA[index];
final Vector b = coeffB[index];
final Vector c = coeffC[index];
final Vector d = coeffD[index];
final Vector3 a = coeffA[index];
final Vector3 b = coeffB[index];
final Vector3 c = coeffC[index];
final Vector3 d = coeffD[index];
return a.multiply(remainder).add(b).multiply(remainder).add(c).multiply(remainder).add(d);
}
@Override
public Vector get1stDerivative(double position) {
public Vector3 get1stDerivative(double position) {
if (coeffA == null)
throw new IllegalStateException("Must call setNodes first.");
@ -170,9 +170,9 @@ public class KochanekBartelsInterpolation implements Interpolation {
final int index = (int) Math.floor(position);
//final double remainder = position - index;
final Vector a = coeffA[index];
final Vector b = coeffB[index];
final Vector c = coeffC[index];
final Vector3 a = coeffA[index];
final Vector3 b = coeffB[index];
final Vector3 c = coeffC[index];
return a.multiply(1.5*position - 3.0*index).add(b).multiply(2.0*position).add(a.multiply(1.5*index).subtract(b).multiply(2.0*index)).add(c).multiply(scaling);
}
@ -219,9 +219,9 @@ public class KochanekBartelsInterpolation implements Interpolation {
}
private double arcLengthRecursive(int index, double remainderLeft, double remainderRight) {
final Vector a = coeffA[index].multiply(3.0);
final Vector b = coeffB[index].multiply(2.0);
final Vector c = coeffC[index];
final Vector3 a = coeffA[index].multiply(3.0);
final Vector3 b = coeffB[index].multiply(2.0);
final Vector3 c = coeffC[index];
final int nPoints = 8;

View File

@ -23,7 +23,7 @@ package com.sk89q.worldedit.math.interpolation;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.Vector3;
import java.util.List;
@ -42,7 +42,7 @@ public class LinearInterpolation implements Interpolation {
}
@Override
public Vector getPosition(double position) {
public Vector3 getPosition(double position) {
if (nodes == null)
throw new IllegalStateException("Must call setNodes first.");
@ -54,8 +54,8 @@ public class LinearInterpolation implements Interpolation {
final int index1 = (int) Math.floor(position);
final double remainder = position - index1;
final Vector position1 = nodes.get(index1).getPosition();
final Vector position2 = nodes.get(index1 + 1).getPosition();
final Vector3 position1 = nodes.get(index1).getPosition();
final Vector3 position2 = nodes.get(index1 + 1).getPosition();
return position1.multiply(1.0 - remainder).add(position2.multiply(remainder));
}
@ -76,7 +76,7 @@ public class LinearInterpolation implements Interpolation {
*/
@Override
public Vector get1stDerivative(double position) {
public Vector3 get1stDerivative(double position) {
if (nodes == null)
throw new IllegalStateException("Must call setNodes first.");
@ -87,8 +87,8 @@ public class LinearInterpolation implements Interpolation {
final int index1 = (int) Math.floor(position);
final Vector position1 = nodes.get(index1).getPosition();
final Vector position2 = nodes.get(index1 + 1).getPosition();
final Vector3 position1 = nodes.get(index1).getPosition();
final Vector3 position2 = nodes.get(index1 + 1).getPosition();
return position2.subtract(position1);
}
@ -135,8 +135,8 @@ public class LinearInterpolation implements Interpolation {
}
private double arcLengthRecursive(int index, double remainderA, double remainderB) {
final Vector position1 = nodes.get(index).getPosition();
final Vector position2 = nodes.get(index + 1).getPosition();
final Vector3 position1 = nodes.get(index).getPosition();
final Vector3 position2 = nodes.get(index + 1).getPosition();
return position1.distance(position2) * (remainderB - remainderA);
}

View File

@ -21,7 +21,7 @@
package com.sk89q.worldedit.math.interpolation;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.Vector3;
/**
* Represents a node for interpolation.
@ -31,14 +31,14 @@ import com.sk89q.worldedit.Vector;
*/
public class Node {
private Vector position;
private Vector3 position;
private double tension;
private double bias;
private double continuity;
public Node() {
this(new Vector(0, 0, 0));
this(new Vector3(0, 0, 0));
}
public Node(Node other) {
@ -49,16 +49,16 @@ public class Node {
this.continuity = other.continuity;
}
public Node(Vector position) {
public Node(Vector3 position) {
this.position = position;
}
public Vector getPosition() {
public Vector3 getPosition() {
return position;
}
public void setPosition(Vector position) {
public void setPosition(Vector3 position) {
this.position = position;
}

View File

@ -23,7 +23,7 @@ package com.sk89q.worldedit.math.interpolation;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.Vector3;
import java.util.List;
import java.util.Map.Entry;
@ -65,7 +65,7 @@ public class ReparametrisingInterpolation implements Interpolation {
}
@Override
public Vector getPosition(double position) {
public Vector3 getPosition(double position) {
if (position > 1)
return null;
@ -73,7 +73,7 @@ public class ReparametrisingInterpolation implements Interpolation {
}
@Override
public Vector get1stDerivative(double position) {
public Vector3 get1stDerivative(double position) {
if (position > 1)
return null;

View File

@ -19,8 +19,9 @@
package com.sk89q.worldedit.math.noise;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.math.Vector2;
import com.sk89q.worldedit.math.Vector3;
import net.royawesome.jlibnoise.module.Module;
import java.util.Random;
@ -46,12 +47,12 @@ abstract class JLibNoiseGenerator<V extends Module> implements NoiseGenerator {
public abstract int getSeed();
@Override
public float noise(Vector2D position) {
public float noise(Vector2 position) {
return forceRange(module.GetValue(position.getX(), 0, position.getZ()));
}
@Override
public float noise(Vector position) {
public float noise(Vector3 position) {
return forceRange(module.GetValue(position.getX(), position.getY(), position.getZ()));
}

View File

@ -19,8 +19,8 @@
package com.sk89q.worldedit.math.noise;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.math.Vector2;
import com.sk89q.worldedit.math.Vector3;
/**
* Generates noise in a deterministic or non-deterministic manner.
@ -34,7 +34,7 @@ public interface NoiseGenerator {
* @param position the position
* @return a noise value between 0 (inclusive) and 1 (inclusive)
*/
float noise(Vector2D position);
float noise(Vector2 position);
/**
* Get the noise value for the given position. The returned value may
@ -43,6 +43,6 @@ public interface NoiseGenerator {
* @param position the position
* @return a noise value between 0 (inclusive) and 1 (inclusive)
*/
float noise(Vector position);
float noise(Vector3 position);
}

View File

@ -19,8 +19,8 @@
package com.sk89q.worldedit.math.noise;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.math.Vector2;
import com.sk89q.worldedit.math.Vector3;
import java.util.Random;
@ -50,12 +50,12 @@ public class RandomNoise implements NoiseGenerator {
}
@Override
public float noise(Vector2D position) {
public float noise(Vector2 position) {
return random.nextFloat();
}
@Override
public float noise(Vector position) {
public float noise(Vector3 position) {
return random.nextFloat();
}

View File

@ -19,8 +19,9 @@
package com.sk89q.worldedit.math.transform;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MathUtils;
import com.sk89q.worldedit.math.Vector3;
/**
* An affine transform.
@ -236,7 +237,11 @@ public class AffineTransform implements Transform {
n20, n21, n22, n23);
}
public AffineTransform translate(Vector vec) {
public AffineTransform translate(Vector3 vec) {
return translate(vec.getX(), vec.getY(), vec.getZ());
}
public AffineTransform translate(BlockVector3 vec) {
return translate(vec.getX(), vec.getY(), vec.getZ());
}
@ -282,13 +287,13 @@ public class AffineTransform implements Transform {
return concatenate(new AffineTransform(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0));
}
public AffineTransform scale(Vector vec) {
public AffineTransform scale(Vector3 vec) {
return scale(vec.getX(), vec.getY(), vec.getZ());
}
@Override
public Vector apply(Vector vector) {
return new Vector(
public Vector3 apply(Vector3 vector) {
return new Vector3(
vector.getX() * m00 + vector.getY() * m01 + vector.getZ() * m02 + m03,
vector.getX() * m10 + vector.getY() * m11 + vector.getZ() * m12 + m13,
vector.getX() * m20 + vector.getY() * m21 + vector.getZ() * m22 + m23);

View File

@ -21,7 +21,7 @@ package com.sk89q.worldedit.math.transform;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.Vector3;
import java.util.ArrayList;
import java.util.Arrays;
@ -66,7 +66,7 @@ public class CombinedTransform implements Transform {
}
@Override
public Vector apply(Vector vector) {
public Vector3 apply(Vector3 vector) {
for (Transform transform : transforms) {
vector = transform.apply(vector);
}

View File

@ -19,7 +19,7 @@
package com.sk89q.worldedit.math.transform;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.Vector3;
/**
* Makes no transformation to given vectors.
@ -32,7 +32,7 @@ public class Identity implements Transform {
}
@Override
public Vector apply(Vector vector) {
public Vector3 apply(Vector3 vector) {
return vector;
}

View File

@ -19,10 +19,10 @@
package com.sk89q.worldedit.math.transform;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.Vector3;
/**
* Makes a transformation of {@link Vector}s.
* Makes a transformation of {@link Vector3}s.
*/
public interface Transform {
@ -41,7 +41,7 @@ public interface Transform {
* @param input the input
* @return the result
*/
Vector apply(Vector input);
Vector3 apply(Vector3 input);
/**
* Create a new inverse transform.