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)));
+ }
}