Add gaussian methods to UtilMath

This commit is contained in:
Graphica 2017-06-28 01:28:39 -04:00
parent dddeb69391
commit e9fea23382
1 changed files with 118 additions and 0 deletions

View File

@ -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 <code>double[point #][x=0, y=1, z=3]</code>.
*/
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 <code>double[point #][x=0, y=1, z=3]</code>.
*/
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. <br>
*
* <b>This method only accepts positive values for all of its arguments.</b> <br>
*
* 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. <br>
*
* <b>This method only accepts positive values for all of its arguments.</b> <br>
*
* 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)));
}
}