From 3fd9f09e01d7af7e811309521ea52f809c760e44 Mon Sep 17 00:00:00 2001 From: sk89q Date: Sat, 15 Jan 2011 13:43:09 -0800 Subject: Moved org.bukkit.Vector to org.bukkit.util. --- src/main/java/org/bukkit/Location.java | 2 + src/main/java/org/bukkit/Vector.java | 614 -------------------------- src/main/java/org/bukkit/World.java | 1 + src/main/java/org/bukkit/entity/Vehicle.java | 2 +- src/main/java/org/bukkit/util/Vector.java | 616 +++++++++++++++++++++++++++ 5 files changed, 620 insertions(+), 615 deletions(-) delete mode 100644 src/main/java/org/bukkit/Vector.java create mode 100644 src/main/java/org/bukkit/util/Vector.java diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java index 0fffe007..972fdaf8 100644 --- a/src/main/java/org/bukkit/Location.java +++ b/src/main/java/org/bukkit/Location.java @@ -1,6 +1,8 @@ package org.bukkit; +import org.bukkit.util.Vector; + /** * Represents a 3-dimensional position in a world */ diff --git a/src/main/java/org/bukkit/Vector.java b/src/main/java/org/bukkit/Vector.java deleted file mode 100644 index 21445c44..00000000 --- a/src/main/java/org/bukkit/Vector.java +++ /dev/null @@ -1,614 +0,0 @@ -package org.bukkit; - -import java.util.Random; - -/** - * Represents a mutable vector. Because the components of Vectors are mutable, - * storing Vectors long term may be dangerous if passing code modifies the - * Vector later. If you want to keep around a Vector, it may be wise to call - * clone() in order to get a copy. - * - * @author sk89q - */ -public class Vector implements Cloneable { - private static final long serialVersionUID = -2657651106777219169L; - - private static Random random = new Random(); - - /** - * Threshold for fuzzy equals(). - */ - private static final double epsilon = 0.000001; - - protected double x; - protected double y; - protected double z; - - /** - * Construct the vector with all components as 0. - */ - public Vector() { - this.x = 0; - this.y = 0; - this.z = 0; - } - - /** - * Construct the vector with provided integer components. - * - * @param x - * @param y - * @param z - */ - public Vector(int x, int y, int z) { - this.x = x; - this.y = y; - this.z = z; - } - - /** - * Construct the vector with provided double components. - * - * @param x - * @param y - * @param z - */ - public Vector(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - /** - * Construct the vector with provided float components. - * - * @param x - * @param y - * @param z - */ - public Vector(float x, float y, float z) { - this.x = x; - this.y = y; - this.z = z; - } - - /** - * Adds the vector by another. - * - * @param vec - * @return the same vector - */ - public Vector add(Vector vec) { - x += vec.x; - y += vec.y; - z += vec.z; - return this; - } - - /** - * Subtracts the vector by another. - * - * @param vec - * @return the same vector - */ - public Vector subtract(Vector vec) { - x -= vec.x; - y -= vec.y; - z -= vec.z; - return this; - } - - /** - * Multiplies the vector by another. - * - * @param vec - * @return the same vector - */ - public Vector multiply(Vector vec) { - x *= vec.x; - y *= vec.y; - z *= vec.z; - return this; - } - - /** - * Divides the vector by another. - * - * @param vec - * @return the same vector - */ - public Vector divide(Vector vec) { - x /= vec.x; - y /= vec.y; - z /= vec.z; - return this; - } - - /** - * Gets the magnitude of the vector, defined as sqrt(x^2+y^2+z^2). The value - * of this method is not cached and uses a costly square-root function, so - * do not repeatedly call this method to get the vector's magnitude. NaN - * will be returned if the inner result of the sqrt() function overflows, - * which will be caused if the length is too long. - * - * @return the magnitude - */ - public double length() { - return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)); - } - - /** - * Gets the magnitude of the vector squared. - * - * @return the magnitude - */ - public double lengthSquared() { - return Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2); - } - - /** - * Get the distance between this vector and another. The value - * of this method is not cached and uses a costly square-root function, so - * do not repeatedly call this method to get the vector's magnitude. NaN - * will be returned if the inner result of the sqrt() function overflows, - * which will be caused if the distance is too long. - * - * @return the distance - */ - public double distance(Vector o) { - return Math.sqrt(Math.pow(x - o.x, 2) + Math.pow(y - o.y, 2) - + Math.pow(z - o.z, 2)); - } - - /** - * Get the squared distance between this vector and another. - * - * @return the distance - */ - public double distanceSquared(Vector o) { - return Math.pow(x - o.x, 2) + Math.pow(y - o.y, 2) - + Math.pow(z - o.z, 2); - } - - /** - * Gets the angle between this vector and another in radians. - * - * @param other - * @return angle in radians - */ - public float angle(Vector other) { - double dot = dot(other) / (length() * other.length()); - return (float)Math.acos(dot); - } - - /** - * Sets this vector to the midpoint between this vector and another. - * - * @param other - * @return this same vector (now a midpoint) - */ - public Vector midpoint(Vector other) { - x = (x + other.x) / 2; - y = (y + other.y) / 2; - z = (z + other.z) / 2; - return this; - } - - /** - * Gets a new midpoint vector between this vector and another. - * - * @param other - * @return a new midpoint vector - */ - public Vector getMidpoint(Vector other) { - x = (x + other.x) / 2; - y = (y + other.y) / 2; - z = (z + other.z) / 2; - return new Vector(x, y, z); - } - - /** - * Performs scalar multiplication, multiplying all components with a scalar. - * - * @param m - * @return the same vector - */ - public Vector multiply(int m) { - x *= m; - y *= m; - z *= m; - return this; - } - - /** - * Performs scalar multiplication, multiplying all components with a scalar. - * - * @param m - * @return the same vector - */ - public Vector multiply(double m) { - x *= m; - y *= m; - z *= m; - return this; - } - - /** - * Performs scalar multiplication, multiplying all components with a scalar. - * - * @param m - * @return the same vector - */ - public Vector multiply(float m) { - x *= m; - y *= m; - z *= m; - return this; - } - - /** - * Calculates the dot product of this vector with another. The dot product - * is defined as x1*x2+y1*y2+z1*z2. The returned value is a scalar. - * - * @param other - * @return dot product - */ - public double dot(Vector other) { - return x * other.x + y * other.y + z * other.z; - } - - /** - * Calculates the cross product of this vector with another. The cross - * product is defined as: - * - * x = y1 * z2 - y2 * z1
- * y = z1 * x2 - z2 * x1
- * z = x1 * y2 - x2 * y1 - * - * @param o - * @return the same vector - */ - public Vector crossProduct(Vector o) { - double newX = y * o.z - o.y * z; - double newY = z * o.x - o.z * x; - double newZ = x * o.y - o.x * y; - x = newX; - y = newY; - z = newZ; - return this; - } - - /** - * Converts this vector to a unit vector (a vector with length of 1). - * - * @return the same vector - */ - public Vector normalize() { - double length = length(); - - x /= length; - y /= length; - z /= length; - - return this; - } - - /** - * Zero this vector's components. - * - * @return the same vector - */ - public Vector zero() { - x = 0; - y = 0; - z = 0; - return this; - } - - /** - * Returns whether this vector is in an axis-aligned bounding box. - * The minimum and maximum vectors given must be truly the minimum and - * maximum X, Y and Z components. - * - * @param min - * @param max - * @return whether this vector is in the AABB - */ - public boolean isInAABB(Vector min, Vector max) { - return x >= min.x && x <= max.x - && y >= min.y && y <= max.y - && z >= min.z && z <= max.z; - } - - /** - * Returns whether this vector is within a sphere. - * - * @param origin - * @param radius - * @return whether this vector is in the sphere - */ - public boolean isInSphere(Vector origin, double radius) { - return (Math.pow(origin.x - x, 2) - + Math.pow(origin.y - y, 2) - + Math.pow(origin.z - z, 2)) - <= Math.pow(radius, 2); - } - - /** - * Gets the X component. - * - * @return - */ - public double getX() { - return x; - } - - /** - * Gets the floored value of the X component, indicating the block that - * this vector is contained with. - * - * @return block X - */ - public int getBlockX() { - return (int)Math.floor(x); - } - - /** - * Gets the Y component. - * - * @return - */ - public double getY() { - return y; - } - - /** - * Gets the floored value of the Y component, indicating the block that - * this vector is contained with. - * - * @return block y - */ - public int getBlockY() { - return (int)Math.floor(y); - } - - /** - * Gets the Z component. - * - * @return - */ - public double getZ() { - return z; - } - - /** - * Gets the floored value of the Z component, indicating the block that - * this vector is contained with. - * - * @return block z - */ - public int getBlockZ() { - return (int)Math.floor(z); - } - - /** - * Set the X component. - * - * @param x - * @return x - */ - public Vector setX(int x) { - this.x = x; - return this; - } - - /** - * Set the X component. - * - * @param x - * @return x - */ - public Vector setX(double x) { - this.x = x; - return this; - } - - /** - * Set the X component. - * - * @param x - * @return x - */ - public Vector setX(float x) { - this.x = x; - return this; - } - - /** - * Set the Y component. - * - * @param y - * @return y - */ - public Vector setY(int y) { - this.y = y; - return this; - } - - /** - * Set the Y component. - * - * @param y - * @return y - */ - public Vector setY(double y) { - this.y = y; - return this; - } - - /** - * Set the Y component. - * - * @param y - * @return y - */ - public Vector setY(float y) { - this.y = y; - return this; - } - - /** - * Set the Z component. - * - * @param z - * @return z - */ - public Vector setZ(int z) { - this.z = z; - return this; - } - - /** - * Set the Z component. - * - * @param z - * @return z - */ - public Vector setZ(double z) { - this.z = z; - return this; - } - - /** - * Set the Z component. - * - * @param z - * @return z - */ - public Vector setZ(float z) { - this.z = z; - return this; - } - - /** - * Checks to see if two objects are equal. - * - * Only two Vectors can ever return true. This method uses a fuzzy match - * to account for floating point errors. The epsilon can be retrieved - * with epsilon. - */ - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Vector)) { - return false; - } - - Vector other = (Vector)obj; - - return Math.abs(x - other.x) < epsilon - && Math.abs(y - other.y) < epsilon - && Math.abs(z - other.z) < epsilon; - } - - /** - * Returns a hash code for this vector. Due to floating point errors, this - * hash code should not be used in hash tables of any sort. - * - * @return hash code - */ - @Override - public int hashCode() { - return ((int)Double.doubleToLongBits(x) >> 13) ^ - ((int)Double.doubleToLongBits(y) >> 7) ^ - (int)Double.doubleToLongBits(z); - } - - /** - * Get a new vector. - * - * @return vector - */ - @Override - public Vector clone() { - return new Vector(x, y, z); - } - - /** - * Returns this vector's components as x,y,z. - * - */ - @Override - public String toString() { - return x + "," + y + "," + z; - } - - /** - * Gets a Location version of this vector with yaw and pitch being 0. - * - * @param world - * @return the location - */ - public Location toLocation(World world) { - return new Location(world, x, y, z); - } - - /** - * Gets a Location version of this vector. - * - * @param world - * @return the location - */ - public Location toLocation(World world, float yaw, float pitch) { - return new Location(world, x, y, z, yaw, pitch); - } - - /** - * Get the threshold used for equals(). - * - * @return - */ - public static double getEpsilon() { - return epsilon; - } - - /** - * Gets the minimum components of two vectors. - * - * @param v1 - * @param v2 - * @return minimum - */ - public static Vector getMinimum(Vector v1, Vector v2) { - return new Vector( - Math.min(v1.x, v2.x), - Math.min(v1.y, v2.y), - Math.min(v1.z, v2.z)); - } - - /** - * Gets the maximum components of two vectors. - * - * @param v1 - * @param v2 - * @return maximum - */ - public static Vector getMaximum(Vector v1, Vector v2) { - return new Vector( - Math.max(v1.x, v2.x), - Math.max(v1.y, v2.y), - Math.max(v1.z, v2.z)); - } - - /** - * Gets a random vector with components having a random value between - * 0 and 1. - * - * @return - */ - public static Vector getRandom() { - return new Vector( - random.nextDouble(), - random.nextDouble(), - random.nextDouble()); - } -} diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java index 1621095b..105dd7ec 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -3,6 +3,7 @@ package org.bukkit; import org.bukkit.block.Block; import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; import org.bukkit.entity.ItemDrop; import org.bukkit.entity.PoweredMinecart; import org.bukkit.entity.Minecart; diff --git a/src/main/java/org/bukkit/entity/Vehicle.java b/src/main/java/org/bukkit/entity/Vehicle.java index 1d618913..36738651 100644 --- a/src/main/java/org/bukkit/entity/Vehicle.java +++ b/src/main/java/org/bukkit/entity/Vehicle.java @@ -1,6 +1,6 @@ package org.bukkit.entity; -import org.bukkit.Vector; +import org.bukkit.util.Vector; /** * Represents a vehicle entity. diff --git a/src/main/java/org/bukkit/util/Vector.java b/src/main/java/org/bukkit/util/Vector.java new file mode 100644 index 00000000..e52b6a42 --- /dev/null +++ b/src/main/java/org/bukkit/util/Vector.java @@ -0,0 +1,616 @@ +package org.bukkit.util; + +import java.util.Random; +import org.bukkit.Location; +import org.bukkit.World; + +/** + * Represents a mutable vector. Because the components of Vectors are mutable, + * storing Vectors long term may be dangerous if passing code modifies the + * Vector later. If you want to keep around a Vector, it may be wise to call + * clone() in order to get a copy. + * + * @author sk89q + */ +public class Vector implements Cloneable { + private static final long serialVersionUID = -2657651106777219169L; + + private static Random random = new Random(); + + /** + * Threshold for fuzzy equals(). + */ + private static final double epsilon = 0.000001; + + protected double x; + protected double y; + protected double z; + + /** + * Construct the vector with all components as 0. + */ + public Vector() { + this.x = 0; + this.y = 0; + this.z = 0; + } + + /** + * Construct the vector with provided integer components. + * + * @param x + * @param y + * @param z + */ + public Vector(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Construct the vector with provided double components. + * + * @param x + * @param y + * @param z + */ + public Vector(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Construct the vector with provided float components. + * + * @param x + * @param y + * @param z + */ + public Vector(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Adds the vector by another. + * + * @param vec + * @return the same vector + */ + public Vector add(Vector vec) { + x += vec.x; + y += vec.y; + z += vec.z; + return this; + } + + /** + * Subtracts the vector by another. + * + * @param vec + * @return the same vector + */ + public Vector subtract(Vector vec) { + x -= vec.x; + y -= vec.y; + z -= vec.z; + return this; + } + + /** + * Multiplies the vector by another. + * + * @param vec + * @return the same vector + */ + public Vector multiply(Vector vec) { + x *= vec.x; + y *= vec.y; + z *= vec.z; + return this; + } + + /** + * Divides the vector by another. + * + * @param vec + * @return the same vector + */ + public Vector divide(Vector vec) { + x /= vec.x; + y /= vec.y; + z /= vec.z; + return this; + } + + /** + * Gets the magnitude of the vector, defined as sqrt(x^2+y^2+z^2). The value + * of this method is not cached and uses a costly square-root function, so + * do not repeatedly call this method to get the vector's magnitude. NaN + * will be returned if the inner result of the sqrt() function overflows, + * which will be caused if the length is too long. + * + * @return the magnitude + */ + public double length() { + return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)); + } + + /** + * Gets the magnitude of the vector squared. + * + * @return the magnitude + */ + public double lengthSquared() { + return Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2); + } + + /** + * Get the distance between this vector and another. The value + * of this method is not cached and uses a costly square-root function, so + * do not repeatedly call this method to get the vector's magnitude. NaN + * will be returned if the inner result of the sqrt() function overflows, + * which will be caused if the distance is too long. + * + * @return the distance + */ + public double distance(Vector o) { + return Math.sqrt(Math.pow(x - o.x, 2) + Math.pow(y - o.y, 2) + + Math.pow(z - o.z, 2)); + } + + /** + * Get the squared distance between this vector and another. + * + * @return the distance + */ + public double distanceSquared(Vector o) { + return Math.pow(x - o.x, 2) + Math.pow(y - o.y, 2) + + Math.pow(z - o.z, 2); + } + + /** + * Gets the angle between this vector and another in radians. + * + * @param other + * @return angle in radians + */ + public float angle(Vector other) { + double dot = dot(other) / (length() * other.length()); + return (float)Math.acos(dot); + } + + /** + * Sets this vector to the midpoint between this vector and another. + * + * @param other + * @return this same vector (now a midpoint) + */ + public Vector midpoint(Vector other) { + x = (x + other.x) / 2; + y = (y + other.y) / 2; + z = (z + other.z) / 2; + return this; + } + + /** + * Gets a new midpoint vector between this vector and another. + * + * @param other + * @return a new midpoint vector + */ + public Vector getMidpoint(Vector other) { + x = (x + other.x) / 2; + y = (y + other.y) / 2; + z = (z + other.z) / 2; + return new Vector(x, y, z); + } + + /** + * Performs scalar multiplication, multiplying all components with a scalar. + * + * @param m + * @return the same vector + */ + public Vector multiply(int m) { + x *= m; + y *= m; + z *= m; + return this; + } + + /** + * Performs scalar multiplication, multiplying all components with a scalar. + * + * @param m + * @return the same vector + */ + public Vector multiply(double m) { + x *= m; + y *= m; + z *= m; + return this; + } + + /** + * Performs scalar multiplication, multiplying all components with a scalar. + * + * @param m + * @return the same vector + */ + public Vector multiply(float m) { + x *= m; + y *= m; + z *= m; + return this; + } + + /** + * Calculates the dot product of this vector with another. The dot product + * is defined as x1*x2+y1*y2+z1*z2. The returned value is a scalar. + * + * @param other + * @return dot product + */ + public double dot(Vector other) { + return x * other.x + y * other.y + z * other.z; + } + + /** + * Calculates the cross product of this vector with another. The cross + * product is defined as: + * + * x = y1 * z2 - y2 * z1
+ * y = z1 * x2 - z2 * x1
+ * z = x1 * y2 - x2 * y1 + * + * @param o + * @return the same vector + */ + public Vector crossProduct(Vector o) { + double newX = y * o.z - o.y * z; + double newY = z * o.x - o.z * x; + double newZ = x * o.y - o.x * y; + x = newX; + y = newY; + z = newZ; + return this; + } + + /** + * Converts this vector to a unit vector (a vector with length of 1). + * + * @return the same vector + */ + public Vector normalize() { + double length = length(); + + x /= length; + y /= length; + z /= length; + + return this; + } + + /** + * Zero this vector's components. + * + * @return the same vector + */ + public Vector zero() { + x = 0; + y = 0; + z = 0; + return this; + } + + /** + * Returns whether this vector is in an axis-aligned bounding box. + * The minimum and maximum vectors given must be truly the minimum and + * maximum X, Y and Z components. + * + * @param min + * @param max + * @return whether this vector is in the AABB + */ + public boolean isInAABB(Vector min, Vector max) { + return x >= min.x && x <= max.x + && y >= min.y && y <= max.y + && z >= min.z && z <= max.z; + } + + /** + * Returns whether this vector is within a sphere. + * + * @param origin + * @param radius + * @return whether this vector is in the sphere + */ + public boolean isInSphere(Vector origin, double radius) { + return (Math.pow(origin.x - x, 2) + + Math.pow(origin.y - y, 2) + + Math.pow(origin.z - z, 2)) + <= Math.pow(radius, 2); + } + + /** + * Gets the X component. + * + * @return + */ + public double getX() { + return x; + } + + /** + * Gets the floored value of the X component, indicating the block that + * this vector is contained with. + * + * @return block X + */ + public int getBlockX() { + return (int)Math.floor(x); + } + + /** + * Gets the Y component. + * + * @return + */ + public double getY() { + return y; + } + + /** + * Gets the floored value of the Y component, indicating the block that + * this vector is contained with. + * + * @return block y + */ + public int getBlockY() { + return (int)Math.floor(y); + } + + /** + * Gets the Z component. + * + * @return + */ + public double getZ() { + return z; + } + + /** + * Gets the floored value of the Z component, indicating the block that + * this vector is contained with. + * + * @return block z + */ + public int getBlockZ() { + return (int)Math.floor(z); + } + + /** + * Set the X component. + * + * @param x + * @return x + */ + public Vector setX(int x) { + this.x = x; + return this; + } + + /** + * Set the X component. + * + * @param x + * @return x + */ + public Vector setX(double x) { + this.x = x; + return this; + } + + /** + * Set the X component. + * + * @param x + * @return x + */ + public Vector setX(float x) { + this.x = x; + return this; + } + + /** + * Set the Y component. + * + * @param y + * @return y + */ + public Vector setY(int y) { + this.y = y; + return this; + } + + /** + * Set the Y component. + * + * @param y + * @return y + */ + public Vector setY(double y) { + this.y = y; + return this; + } + + /** + * Set the Y component. + * + * @param y + * @return y + */ + public Vector setY(float y) { + this.y = y; + return this; + } + + /** + * Set the Z component. + * + * @param z + * @return z + */ + public Vector setZ(int z) { + this.z = z; + return this; + } + + /** + * Set the Z component. + * + * @param z + * @return z + */ + public Vector setZ(double z) { + this.z = z; + return this; + } + + /** + * Set the Z component. + * + * @param z + * @return z + */ + public Vector setZ(float z) { + this.z = z; + return this; + } + + /** + * Checks to see if two objects are equal. + * + * Only two Vectors can ever return true. This method uses a fuzzy match + * to account for floating point errors. The epsilon can be retrieved + * with epsilon. + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Vector)) { + return false; + } + + Vector other = (Vector)obj; + + return Math.abs(x - other.x) < epsilon + && Math.abs(y - other.y) < epsilon + && Math.abs(z - other.z) < epsilon; + } + + /** + * Returns a hash code for this vector. Due to floating point errors, this + * hash code should not be used in hash tables of any sort. + * + * @return hash code + */ + @Override + public int hashCode() { + return ((int)Double.doubleToLongBits(x) >> 13) ^ + ((int)Double.doubleToLongBits(y) >> 7) ^ + (int)Double.doubleToLongBits(z); + } + + /** + * Get a new vector. + * + * @return vector + */ + @Override + public Vector clone() { + return new Vector(x, y, z); + } + + /** + * Returns this vector's components as x,y,z. + * + */ + @Override + public String toString() { + return x + "," + y + "," + z; + } + + /** + * Gets a Location version of this vector with yaw and pitch being 0. + * + * @param world + * @return the location + */ + public Location toLocation(World world) { + return new Location(world, x, y, z); + } + + /** + * Gets a Location version of this vector. + * + * @param world + * @return the location + */ + public Location toLocation(World world, float yaw, float pitch) { + return new Location(world, x, y, z, yaw, pitch); + } + + /** + * Get the threshold used for equals(). + * + * @return + */ + public static double getEpsilon() { + return epsilon; + } + + /** + * Gets the minimum components of two vectors. + * + * @param v1 + * @param v2 + * @return minimum + */ + public static Vector getMinimum(Vector v1, Vector v2) { + return new Vector( + Math.min(v1.x, v2.x), + Math.min(v1.y, v2.y), + Math.min(v1.z, v2.z)); + } + + /** + * Gets the maximum components of two vectors. + * + * @param v1 + * @param v2 + * @return maximum + */ + public static Vector getMaximum(Vector v1, Vector v2) { + return new Vector( + Math.max(v1.x, v2.x), + Math.max(v1.y, v2.y), + Math.max(v1.z, v2.z)); + } + + /** + * Gets a random vector with components having a random value between + * 0 and 1. + * + * @return + */ + public static Vector getRandom() { + return new Vector( + random.nextDouble(), + random.nextDouble(), + random.nextDouble()); + } +} -- cgit v1.2.3