diff --git a/Plugins/Mineplex.Core.Common.Base/src/mineplex/core/common/util/UtilMath.java b/Plugins/Mineplex.Core.Common.Base/src/mineplex/core/common/util/UtilMath.java index 5e37e0ac5..1b3b40835 100644 --- a/Plugins/Mineplex.Core.Common.Base/src/mineplex/core/common/util/UtilMath.java +++ b/Plugins/Mineplex.Core.Common.Base/src/mineplex/core/common/util/UtilMath.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; import org.bukkit.Location; import org.bukkit.entity.Entity; @@ -13,6 +14,8 @@ import org.bukkit.util.Vector; public class UtilMath { + public static final double TAU = Math.PI * 2D; + public static double trim(int degree, double d) { String format = "#.#"; @@ -332,4 +335,119 @@ public class UtilMath return min; } + + /** + * Creates an array of points, arranged in a circle normal to a vector. + * + * @param center The center of the circle. + * @param normal A vector normal to the circle. + * @param radius The radius of the circle. + * @param points How many points to make up the circle. + * + * @return An array of points of the form double[point #][x=0, y=1, z=3]. + */ + public static double[][] normalCircle(Location center, Vector normal, double radius, int points) + { + return normalCircle(center.toVector(), normal, radius, points); + } + + /** + * Creates an array of points, arranged in a circle normal to a vector. + * + * @param center The center of the circle. + * @param normal A vector normal to the circle. + * @param radius The radius of the circle. + * @param points How many points to make up the circle. + * + * @return An array of points of the form double[point #][x=0, y=1, z=3]. + */ + public static double[][] normalCircle(Vector center, Vector normal, double radius, int points) + { + Vector n = normal.clone().normalize(); + Vector a = n.clone().add(new Vector(1, 1, 1)).crossProduct(n).normalize(); + Vector b = n.getCrossProduct(a).normalize(); + + double[][] data = new double[points][3]; + + double interval = TAU / points; + double theta = 0; + + for (int i = 0; i < points; i++) + { + data[i][0] = center.getX() + (radius * ((Math.cos(theta) * a.getX()) + (Math.sin(theta) * b.getX()))); + data[i][1] = center.getY() + (radius * ((Math.cos(theta) * a.getY()) + (Math.sin(theta) * b.getY()))); + data[i][2] = center.getZ() + (radius * ((Math.cos(theta) * a.getZ()) + (Math.sin(theta) * b.getZ()))); + theta += interval; + } + + return data; + } + + /** + * Slightly randomize a location with a standard deviation of one. + * + * @param location The location to randomize. + * + * @return The original location, now gaussian-randomized. + */ + public static Location gauss(Location location) + { + return gauss(location, 1, 1, 1); + } + + /** + * Slightly randomize a vector with a standard deviation of one. + * + * @param vector The location to randomize. + * + * @return The randomized vector, now gaussian-randomized. + */ + public static Vector gauss(Vector vector) + { + return gauss(vector, 1, 1, 1); + } + + /** + * Slightly randomize a location with a standard deviation of one.
+ * + * This method only accepts positive values for all of its arguments.
+ * + * A good parameter set for small offsets is (loc, 10, 10, 10). + * + * @param location The location to randomize. + * @param x A granularity control for the x-axis, higher numbers = less randomness + * @param y A granularity control for the y-axis, higher numbers = less randomness + * @param z A granularity control for the z-axis, higher numbers = less randomness + * + * @return The original location, now gaussian-randomized + */ + public static Location gauss(Location location, double x, double y, double z) + { + return location.clone().add( + x <= 0 ? 0 : (ThreadLocalRandom.current().nextGaussian() / x), + y <= 0 ? 0 : (ThreadLocalRandom.current().nextGaussian() / y), + z <= 0 ? 0 : (ThreadLocalRandom.current().nextGaussian() / z)); + } + + /** + * Slightly randomize a vector with a standard deviation of one.
+ * + * This method only accepts positive values for all of its arguments.
+ * + * A good parameter set for small offsets is (loc, 10, 10, 10). + * + * @param vector The location to randomize. + * @param x A granularity control for the x-axis, higher numbers = less randomness + * @param y A granularity control for the y-axis, higher numbers = less randomness + * @param z A granularity control for the z-axis, higher numbers = less randomness + * + * @return The randomized vector, now gaussian-randomized + */ + public static Vector gauss(Vector vector, double x, double y, double z) + { + return vector.clone().add(new Vector( + x <= 0 ? 0 : (ThreadLocalRandom.current().nextGaussian() / x), + y <= 0 ? 0 : (ThreadLocalRandom.current().nextGaussian() / y), + z <= 0 ? 0 : (ThreadLocalRandom.current().nextGaussian() / z))); + } }