Class GradientVectors

java.lang.Object
com.github.yellowstonegames.grid.GradientVectors

public final class GradientVectors extends Object
Stores arrays representing vectors on the unit hypersphere in 2D through 6D. This is used by PerlinNoise and SimplexNoise, as well as indirectly by all classes that use those. Each constant in this class stores 256 unit vectors in a 1D array, one after the next, but sometimes with padding. See the docs for each constant for more information, but GRADIENTS_2D and GRADIENTS_4D have no padding, and the others have one to three ignored floats after each vector.
  • Field Details

    • GRADIENTS_2D

      public static final float[] GRADIENTS_2D
      256 equidistant points on the 2D unit circle. Each point is stored in 2 floats, and there no padding. The distance from each point to the origin should be 1.0, subject to rounding error.
      The points were randomly rotated to try to avoid correlation on any typical axis; all points used the same rotation to keep their distance to each other and shape.
      This particular set of 256 gradient vectors is either optimal or very close to optimal for this size of a set of vectors.
    • GRADIENTS_3D

      public static final float[] GRADIENTS_3D
      The 32 vertices of a rhombic triacontahedron, normalized to lie on the unit sphere in 3D. Each point is stored in 3 floats, and there is 1 float of padding after each point (to allow easier access to points using bitwise operations). The distance from each point to the origin should be 1.0, subject to rounding error.
      The points were randomly rotated to try to avoid correlation on any typical axis; all points used the same rotation to keep their distance to each other and shape. Each group of 32 vertices is repeated 8 times, each time shuffled differently within that group. That means this holds 256 points, with 8 repeats of each point included in that. If you only look at the first 32 points, each point will be unique.
      This particular set of 32 gradient vectors is either optimal or very close to optimal for a power-of-two-sized set of vectors (except for very small sets like the vertices of a tetrahedron).
    • GRADIENTS_4D

      public static final float[] GRADIENTS_4D
      256 quasi-random 4D unit vectors, generated by taking the "Super-Fibonacci spiral" and gradually adjusting its points until they reached equilibrium. 128 vectors were generated this way, and the remaining 128 are the polar opposite points of each of those vectors (their antipodes). This page by Marc Alexa covers the spiral, though an empirical search found better constants for our specific number of points (128, plus their antipodes).
      Each point is stored in 4 floats, and there is no padding between points. The distance from each point to the origin should be 1.0, subject to rounding error. Each point is unique, and as long as you sample a point in the expected way (starting on a multiple of four, using four sequential floats as the x, y, z, w components), the points will all be unit vectors. The points were shuffled here to avoid any correlation when sampling in sequence.
      This particular set of 256 gradient vectors is fairly close to optimal for a power-of-two-sized set of vectors. A set of 256 unit vectors with all-equal distances to their neighbors can't be made. The minimum distance (in 4D Euclidean space) between any two points in this set is 0.369142885554421 .
      This also doesn't have any easily-noticed visual artifacts, which is much better than the previous set of 64 gradient vectors using a truncated tesseract. Those 64 points were much more likely to lie on straight lines when projected using a certain method, and also had rather clear angles. The "certain method" is to take points on the surface of a sphere in 4D (properly, the "3-sphere" because it has 3 degrees of freedom), and ignore two coordinates while keeping the other two. This should produce 2D points uniformly distributed across the inside of a circle (properly, the "2-ball" because it has 2 degrees of freedom, and apparently a ball is solid, but a sphere is not). Repeating this for each possible pair that can be dropped shows some good views of an otherwise hard-to-contemplate shape. This method does show spirals for certain coordinates (xy and zw show spirals, but xz, zw, and yw do not). This shouldn't be too obvious in practice.
    • GRADIENTS_5D

      public static final float[] GRADIENTS_5D
      Randomly selected points on the 5D unit hypersphere (mathematically, the '4-sphere'). Each point is stored in 5 floats, and there are 3 floats of padding after each point (to allow easier access to points using bitwise operations). The distance from each point to the origin should be 1.0, subject to rounding error; this is implied by the point being on the unit hypersphere, but earlier gradient vectors used a different distance to the origin.
      These 256 points were found by getting 128 points from a Halton sequence (the 3,5,7,11,2 sequence) and their polar opposites, running each through probit() to normal-distribute them, normalizing those points, and then optimizing the resulting points by "nudging" points away from their closest neighbors until equilibrium. For every point on the sphere present here, the polar opposite of that point is also present, ensuring there is no bias along any particular axis. The points were also shuffled, in case they are retrieved by a less-random method (such as iteration).
      This particular set of gradient vectors is almost certainly not optimal, but finding a better one is very, very slow right now. The minimum distance between any two points is 0.49298331.
    • GRADIENTS_6D

      public static final float[] GRADIENTS_6D
      Randomly selected points on the 6D unit hypersphere (mathematically, the '5-sphere'). Each point is stored in 6 floats, and there are 2 floats of padding after each point (to allow easier access to points using bitwise operations). The distance from each point to the origin should be 1.0, subject to rounding error; this is implied by the point being on the unit hypersphere, but earlier gradient vectors used a different distance to the origin.
      These 256 points were found by getting 128 points from a Halton sequence (the 3,5,7,11,2,13 sequence) and their polar opposites, running each through probit() to normal-distribute them, normalizing those points, and then optimizing the resulting points by "nudging" points away from their closest neighbors until equilibrium. For every point on the sphere present here, the polar opposite of that point is also present, ensuring there is no bias along any particular axis. The points were also shuffled, in case they are retrieved by a less-random method (such as iteration).
      This particular set of gradient vectors is almost certainly not optimal, but finding a better one is very, very slow right now. The minimum distance between any two points is 0.63219683.
    • CELLULAR_GRADIENTS_2D

      public static final float[] CELLULAR_GRADIENTS_2D
      The same vectors as GRADIENTS_2D, but scaled by a factor of 0.45f so that they can be used by CellularNoise.
    • CELLULAR_GRADIENTS_3D

      public static final float[] CELLULAR_GRADIENTS_3D
      The same vectors as GRADIENTS_3D, but scaled by a factor of 0.45f so that they can be used by CellularNoise.
    • CELLULAR_GRADIENTS_4D

      public static final float[] CELLULAR_GRADIENTS_4D
      The same vectors as GRADIENTS_4D, but scaled by a factor of 0.45f so that they can be used by CellularNoise.