|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright (c) 2009-2024 jMonkeyEngine
|
|
|
+ * Copyright (c) 2009-2025 jMonkeyEngine
|
|
|
* All rights reserved.
|
|
|
*
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -40,9 +40,10 @@ import java.util.Random;
|
|
|
* @author Various
|
|
|
* @version $Id: FastMath.java,v 1.45 2007/08/26 08:44:20 irrisor Exp $
|
|
|
*/
|
|
|
-final public class FastMath {
|
|
|
- private FastMath() {
|
|
|
- }
|
|
|
+public final class FastMath {
|
|
|
+
|
|
|
+ private FastMath() {}
|
|
|
+
|
|
|
/**
|
|
|
* A "close to zero" double epsilon value for use
|
|
|
*/
|
|
@@ -489,10 +490,8 @@ final public class FastMath {
|
|
|
if (fValue < 1.0f) {
|
|
|
return (float) Math.acos(fValue);
|
|
|
}
|
|
|
-
|
|
|
return 0.0f;
|
|
|
}
|
|
|
-
|
|
|
return PI;
|
|
|
}
|
|
|
|
|
@@ -511,10 +510,8 @@ final public class FastMath {
|
|
|
if (fValue < 1.0f) {
|
|
|
return (float) Math.asin(fValue);
|
|
|
}
|
|
|
-
|
|
|
return HALF_PI;
|
|
|
}
|
|
|
-
|
|
|
return -HALF_PI;
|
|
|
}
|
|
|
|
|
@@ -844,35 +841,111 @@ final public class FastMath {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Returns a random float between 0 and 1.
|
|
|
+ * Generates a pseudorandom {@code float} in the range [0.0, 1.0).
|
|
|
*
|
|
|
- * @return a random float between 0 (inclusive) and 1 (exclusive)
|
|
|
+ * @return A random {@code float} value.
|
|
|
*/
|
|
|
public static float nextRandomFloat() {
|
|
|
return rand.nextFloat();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Returns a random integer between min and max.
|
|
|
+ * Generates a pseudorandom {@code float} in the range [min, max)
|
|
|
*
|
|
|
- * @param min the desired minimum value
|
|
|
- * @param max the desired maximum value
|
|
|
- * @return a random int between min (inclusive) and max (inclusive)
|
|
|
+ * @param min The lower bound (inclusive).
|
|
|
+ * @param max The upper bound (exclusive).
|
|
|
+ * @return A random {@code float} value within the specified range.
|
|
|
*/
|
|
|
- public static int nextRandomInt(int min, int max) {
|
|
|
- return (int) (nextRandomFloat() * (max - min + 1)) + min;
|
|
|
+ public static float nextRandomFloat(float min, float max) {
|
|
|
+ return min + (max - min) * nextRandomFloat();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Choose a pseudo-random, uniformly-distributed integer value from
|
|
|
- * the shared generator.
|
|
|
+ * Generates a pseudorandom, uniformly-distributed {@code int} value.
|
|
|
*
|
|
|
- * @return the next integer value
|
|
|
+ * @return The next pseudorandom {@code int} value.
|
|
|
*/
|
|
|
public static int nextRandomInt() {
|
|
|
return rand.nextInt();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Generates a pseudorandom {@code int} in the range [min, max] (inclusive).
|
|
|
+ *
|
|
|
+ * @param min The lower bound (inclusive).
|
|
|
+ * @param max The upper bound (inclusive).
|
|
|
+ * @return A random {@code int} value within the specified range.
|
|
|
+ */
|
|
|
+ public static int nextRandomInt(int min, int max) {
|
|
|
+ return (int) (nextRandomFloat() * (max - min + 1)) + min;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns a random point on the surface of a sphere with radius 1.0
|
|
|
+ *
|
|
|
+ * @return A new {@link Vector3f} representing a random point on the surface of the unit sphere.
|
|
|
+ */
|
|
|
+ public static Vector3f onUnitSphere() {
|
|
|
+
|
|
|
+ float u = nextRandomFloat();
|
|
|
+ float v = nextRandomFloat();
|
|
|
+
|
|
|
+ // azimuthal angle: The angle between x-axis in radians [0, 2PI]
|
|
|
+ float theta = FastMath.TWO_PI * u;
|
|
|
+ // polar angle: The angle between z-axis in radians [0, PI]
|
|
|
+ float phi = (float) Math.acos(2f * v - 1f);
|
|
|
+
|
|
|
+ float cosPolar = FastMath.cos(phi);
|
|
|
+ float sinPolar = FastMath.sin(phi);
|
|
|
+ float cosAzim = FastMath.cos(theta);
|
|
|
+ float sinAzim = FastMath.sin(theta);
|
|
|
+
|
|
|
+ return new Vector3f(cosAzim * sinPolar, sinAzim * sinPolar, cosPolar);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns a random point inside or on a sphere with radius 1.0
|
|
|
+ * This method uses spherical coordinates combined with a cubed-root radius.
|
|
|
+ *
|
|
|
+ * @return A new {@link Vector3f} representing a random point within the unit sphere.
|
|
|
+ */
|
|
|
+ public static Vector3f insideUnitSphere() {
|
|
|
+ float u = nextRandomFloat();
|
|
|
+ // Azimuthal angle [0, 2PI]
|
|
|
+ float theta = FastMath.TWO_PI * nextRandomFloat();
|
|
|
+ // Polar angle [0, PI] for uniform surface distribution
|
|
|
+ float phi = FastMath.acos(2f * nextRandomFloat() - 1f);
|
|
|
+
|
|
|
+ // For uniform distribution within the volume, radius R should be such that R^3 is uniformly distributed.
|
|
|
+ // So, R = cbrt(random_uniform_0_to_1)
|
|
|
+ float radius = (float) Math.cbrt(u);
|
|
|
+
|
|
|
+ float sinPhi = FastMath.sin(phi);
|
|
|
+ float x = radius * sinPhi * FastMath.cos(theta);
|
|
|
+ float y = radius * sinPhi * FastMath.sin(theta);
|
|
|
+ float z = radius * FastMath.cos(phi);
|
|
|
+
|
|
|
+ return new Vector3f(x, y, z);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns a random point inside or on a circle with radius 1.0.
|
|
|
+ * This method uses polar coordinates combined with a square-root radius.
|
|
|
+ *
|
|
|
+ * @return A new {@link Vector2f} representing a random point within the unit circle.
|
|
|
+ */
|
|
|
+ public static Vector2f insideUnitCircle() {
|
|
|
+ // Angle [0, 2PI]
|
|
|
+ float angle = FastMath.TWO_PI * nextRandomFloat();
|
|
|
+ // For uniform distribution, R^2 is uniform
|
|
|
+ float radius = FastMath.sqrt(nextRandomFloat());
|
|
|
+
|
|
|
+ float x = radius * FastMath.cos(angle);
|
|
|
+ float y = radius * FastMath.sin(angle);
|
|
|
+
|
|
|
+ return new Vector2f(x, y);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Converts a point from Spherical coordinates to Cartesian (using positive
|
|
|
* Y as up) and stores the results in the store var.
|
|
@@ -883,8 +956,7 @@ final public class FastMath {
|
|
|
* @param store storage for the result (modified if not null)
|
|
|
* @return the Cartesian coordinates (either store or a new vector)
|
|
|
*/
|
|
|
- public static Vector3f sphericalToCartesian(Vector3f sphereCoords,
|
|
|
- Vector3f store) {
|
|
|
+ public static Vector3f sphericalToCartesian(Vector3f sphereCoords, Vector3f store) {
|
|
|
if (store == null) {
|
|
|
store = new Vector3f();
|
|
|
}
|
|
@@ -906,8 +978,7 @@ final public class FastMath {
|
|
|
* @return the Cartesian coordinates: x=distance from origin, y=longitude in
|
|
|
* radians, z=latitude in radians (either store or a new vector)
|
|
|
*/
|
|
|
- public static Vector3f cartesianToSpherical(Vector3f cartCoords,
|
|
|
- Vector3f store) {
|
|
|
+ public static Vector3f cartesianToSpherical(Vector3f cartCoords, Vector3f store) {
|
|
|
if (store == null) {
|
|
|
store = new Vector3f();
|
|
|
}
|
|
@@ -936,8 +1007,7 @@ final public class FastMath {
|
|
|
* @param store storage for the result (modified if not null)
|
|
|
* @return the Cartesian coordinates (either store or a new vector)
|
|
|
*/
|
|
|
- public static Vector3f sphericalToCartesianZ(Vector3f sphereCoords,
|
|
|
- Vector3f store) {
|
|
|
+ public static Vector3f sphericalToCartesianZ(Vector3f sphereCoords, Vector3f store) {
|
|
|
if (store == null) {
|
|
|
store = new Vector3f();
|
|
|
}
|
|
@@ -959,8 +1029,7 @@ final public class FastMath {
|
|
|
* @return the Cartesian coordinates: x=distance from origin, y=latitude in
|
|
|
* radians, z=longitude in radians (either store or a new vector)
|
|
|
*/
|
|
|
- public static Vector3f cartesianZToSpherical(Vector3f cartCoords,
|
|
|
- Vector3f store) {
|
|
|
+ public static Vector3f cartesianZToSpherical(Vector3f cartCoords, Vector3f store) {
|
|
|
if (store == null) {
|
|
|
store = new Vector3f();
|
|
|
}
|
|
@@ -982,12 +1051,9 @@ final public class FastMath {
|
|
|
/**
|
|
|
* Takes a value and expresses it in terms of min to max.
|
|
|
*
|
|
|
- * @param val -
|
|
|
- * the angle to normalize (in radians)
|
|
|
- * @param min
|
|
|
- * the lower limit of the range
|
|
|
- * @param max
|
|
|
- * the upper limit of the range
|
|
|
+ * @param val the angle to normalize (in radians)
|
|
|
+ * @param min the lower limit of the range
|
|
|
+ * @param max the upper limit of the range
|
|
|
* @return the normalized angle (also in radians)
|
|
|
*/
|
|
|
public static float normalize(float val, float min, float max) {
|
|
@@ -1143,5 +1209,4 @@ final public class FastMath {
|
|
|
return ((n - 1) | (p - 1)) + 1;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
}
|