Class TuringPattern
java.lang.Object
com.github.yellowstonegames.grid.TuringPattern
A technique for producing organic-seeming patterns via iterative processing of random values (reaction-diffusion).
The fundamental basis for why this looks organic should be credited to Alan Turing, but the specific algorithm should
be credited to Jonathan
McCabe, who has produced significant expansions on the scope the original Turing work covered; you can see
various examples of art he produced using this and related
techniques.
This class tries to provide a fairly raw API so different adjustments can be made on top of it.
This class tries to provide a fairly raw API so different adjustments can be made on top of it.
-
Method Summary
Modifier and TypeMethodDescriptionstatic voidaddNoise(float[] substance, int width, int height, float multiplier, INoise noise, float z, long seed) Simply adds the result of a noise call, multiplied by the given multiplier, to each point in substance.static voidSimply adds the result of a noise call, multiplied by the given multiplier, to each point in substance.static voidAlters the given offset information (as a jagged 2D int array) with the given Noise3D instance and seed, allowing a z position for the 3D component so this can change over time with changing z.static voidAlters the given offset information (as a jagged 2D int array) with the given Noise2D instance and seed.static voidfill(float[][] target, float[] substance) Modifies target in-place so it is filled with as much data as possible from substance.static float[]initialize(int width, int height) Initializes a substance array that can be given to other static methods.static float[]initialize(int width, int height, long seed) Initializes a substance array that can be given to other static methods.static float[]initialize(int width, int height, com.github.tommyettinger.random.EnhancedRandom random) Initializes a substance array that can be given to other static methods.static float[]initialize(int width, int height, INoise noise, long seed) Initializes a substance array that can be given to other static methods.static float[]initializeInto(float[] substance) Refills a substance array that can be given to other static methods.static float[]initializeInto(float[] substance, int width, int height, INoise noise, long seed) Initializes a substance array that can be given to other static methods.static float[]initializeInto(float[] substance, com.github.tommyettinger.random.EnhancedRandom random) Refills a substance array that can be given to other static methods.static voidnormalize(float[] substance) Finds the highest and lowest values in the substance array and modifies the whole array so the lowest and highest values are contracted or expanded to -1.0 and 1.0, respectively, and other values change commensurately.static int[][]offsetsCircle(int width, int height, float radius) Pre-calculates the indices into a substance array that will need to be averaged per point in that array for an activator or inhibitor.static int[][]offsetsCircleInto(int[][] offsets, int width, int height, float radius) Given an offset information array that has been modified and should be returned to its unmodified state, this uses the given width, height, and radius (which should be the same as what this was originally constructed with) to modify offsets in-place as if it was freshly-made.static voidrefit(float[] data) Modifies the data parameter so no value in it is outside the range -1.0 inclusive to 1.0 exclusive.static float[][]reshape(int width, int height, float[] substance) Makes a new 2D float array with the given width and height, using the given substance array for contents.static voidstep(float[] substance, int[][] activator, float activation, int[][] inhibitor, float inhibition) Brings together the other methods to advance the substance simulation by one step, modifying substance in-place.static voidstepPartial(float[] substance, int[][] activator, float activation, int[][] inhibitor, float inhibition) Computes the first part of a step, allowing other adjustments to be mixed in before finishing by callingnormalize(float[]).
-
Method Details
-
initialize
public static float[] initialize(int width, int height) Initializes a substance array that can be given to other static methods.- Parameters:
width- the width of the substance array; should be consistent throughout callsheight- the height of the substance array; should be consistent throughout calls- Returns:
- a 1D float array that represents a 2D array with random contents; should be given to other methods
-
initializeInto
public static float[] initializeInto(float[] substance) Refills a substance array that can be given to other static methods.- Parameters:
substance- a 1D float array that will be modified and filled with random values- Returns:
- substance, after modification; should be given to other methods
-
initialize
public static float[] initialize(int width, int height, long seed) Initializes a substance array that can be given to other static methods.- Parameters:
width- the width of the substance array; should be consistent throughout callsheight- the height of the substance array; should be consistent throughout callsseed- the long seed to use for the random contents- Returns:
- a 1D float array that represents a 2D array with random contents; should be given to other methods
-
initializeInto
public static float[] initializeInto(float[] substance, com.github.tommyettinger.random.EnhancedRandom random) Refills a substance array that can be given to other static methods.- Parameters:
substance- a 1D float array that will be modified and filled with random valuesrandom- any EnhancedRandom from juniper, such asChopRandomorAceRandom- Returns:
- substance, after modification; should be given to other methods
-
initialize
public static float[] initialize(int width, int height, com.github.tommyettinger.random.EnhancedRandom random) Initializes a substance array that can be given to other static methods. Uses an RNG to produce long values that this turns into floats in the desired range (that is, -1.0 to 1.0).- Parameters:
width- the width of the substance array; should be consistent throughout callsheight- the height of the substance array; should be consistent throughout callsrandom- the random number generator responsible for producing random float values- Returns:
- a 1D float array that represents a 2D array with random contents; should be given to other methods
-
initialize
Initializes a substance array that can be given to other static methods. Uses a Noise2D instance (it may or may not use the given seed) to produce values between -1.0 and 1.0.- Parameters:
width- the width of the substance array; should be consistent throughout callsheight- the height of the substance array; should be consistent throughout callsnoise- an INoise instance, such asSimplexNoise.instanceseed- the seed to use with the noise generator- Returns:
- a 1D float array that represents a 2D array with random contents; should be given to other methods
-
initializeInto
public static float[] initializeInto(float[] substance, int width, int height, INoise noise, long seed) Initializes a substance array that can be given to other static methods. Uses a Noise2D instance (it may or may not use the given seed) to produce values between -1.0 and 1.0.- Parameters:
width- the width of the substance array; should be consistent throughout callsheight- the height of the substance array; should be consistent throughout callsnoise- an INoise instance, such asSimplexNoise.instanceseed- the seed to use with the noise generator- Returns:
- a 1D float array that represents a 2D array with random contents; should be given to other methods
-
refit
public static void refit(float[] data) Modifies the data parameter so no value in it is outside the range -1.0 inclusive to 1.0 exclusive. Makes no guarantees about the values this puts in data beyond that they will be inside that range. Has undefined results if any values in data are NaN or are infinite. If all values in data are already in the range, this will still change them, though probably not beyond recognition. Does not return a value because the changes are applied to data in-place.- Parameters:
data- a float array that will be modified in-place so all values in it will be between -1.0 and 1.0
-
offsetsCircleInto
public static int[][] offsetsCircleInto(int[][] offsets, int width, int height, float radius) Given an offset information array that has been modified and should be returned to its unmodified state, this uses the given width, height, and radius (which should be the same as what this was originally constructed with) to modify offsets in-place as if it was freshly-made.- Parameters:
offsets- an offset information array that should have been produced byoffsetsCircle(int, int, float)and may have been distortedwidth- the width of the substance array; should be consistent throughout callsheight- the height of the substance array; should be consistent throughout callsradius- the radius of the circle to- Returns:
- an offset information array, as a jagged 2D int array, that can be passed to
step(float[], int[][], float, int[][], float)
-
offsetsCircle
public static int[][] offsetsCircle(int width, int height, float radius) Pre-calculates the indices into a substance array that will need to be averaged per point in that array for an activator or inhibitor. The radius should usually (by convention) be smaller for an activator and larger for an inhibitor, but very large radii cause this to require significantly more time; consider a maximum of about 20, or less depending on how fast it needs to run vs. quality, and how many generations you expect.- Parameters:
width- the width of the substance array; should be consistent throughout callsheight- the height of the substance array; should be consistent throughout callsradius- the radius of the circle to- Returns:
- an offset information array, as a jagged 2D int array, that can be passed to
step(float[], int[][], float, int[][], float)
-
distort
Alters the given offset information (as a jagged 2D int array) with the given Noise2D instance and seed. This can change the quality of the pattern produced significantly, going from stripes to whorls and fungoid shapes. Modifies offsets in-place, and repeated calls can be a good way to alter the pattern this produces.- Parameters:
offsets- a jagged 2D int array as produced byoffsetsCircle(int, int, float); will be modified!width- the width of the full area that will be used by the TuringPatternheight- the height of the full area that will be used by the TuringPatternnoise- an INoise instance, such asSimplexNoise.instance, that will be used to alter offsetsseed- a seed for the Noise2D
-
distort
public static void distort(int[][] offsets, int width, int height, INoise noise, float z, long seed) Alters the given offset information (as a jagged 2D int array) with the given Noise3D instance and seed, allowing a z position for the 3D component so this can change over time with changing z. This can method change the quality of the pattern produced significantly, going from stripes to whorls and fungoid shapes. Modifies offsets in-place, and repeated calls can be a good way to alter the pattern this produces.- Parameters:
offsets- a jagged 2D int array as produced byoffsetsCircle(int, int, float); will be modified!width- the width of the full area that will be used by the TuringPatternheight- the height of the full area that will be used by the TuringPatternnoise- an INoise instance, such asSimplexNoise.instance, that will be used to alter offsetsz- a z position to be given to the Noise3D along with a point's x and yseed- a seed for the Noise3D
-
step
public static void step(float[] substance, int[][] activator, float activation, int[][] inhibitor, float inhibition) Brings together the other methods to advance the substance simulation by one step, modifying substance in-place. You should have generated substance with either one of the initialize() methods or withrefit(float[]), and the activator and inhibitor should have been produced by calls to an offsets method likeoffsetsCircle(int, int, float), with the same width and height passed to initialize (or if you used refit, the length of the substance array should be equal to width times height). The activation and inhibition parameters should be very small (larger numbers will cause more significant jumps in a simulation, but may be better for single generations; neither amount should have an absolute value larger than 0.1 in general), and inhibition should have the opposite sign of activation.- Parameters:
substance- as produced by initialize; will be modified!activator- as produced by an offsets methodactivation- the small float amount to use when the activator is dominant; should usually be positiveinhibitor- as produced by an offsets methodinhibition- the small float amount to use when the inhibitor is dominant; should usually be negative
-
stepPartial
public static void stepPartial(float[] substance, int[][] activator, float activation, int[][] inhibitor, float inhibition) Computes the first part of a step, allowing other adjustments to be mixed in before finishing by callingnormalize(float[]). A sample adjustment would beaddNoise(float[], int, int, float, INoise, long). This is probably not very useful yet.- Parameters:
substance- as produced by initialize; will be modified!activator- as produced by an offsets methodactivation- the small float amount to use when the activator is dominant; should usually be positiveinhibitor- as produced by an offsets methodinhibition- the small float amount to use when the inhibitor is dominant; should usually be negative- See Also:
-
addNoise
public static void addNoise(float[] substance, int width, int height, float multiplier, INoise noise, long seed) Simply adds the result of a noise call, multiplied by the given multiplier, to each point in substance. Modifies substance in-place.- Parameters:
substance- as produced by initialize; will be modified!width- the width of the substance array; should be consistent throughout callsheight- the height of the substance array; should be consistent throughout callsmultiplier- multiplied with each noise call, so noise (usually too significant) can have its effect reducednoise- an INoise instance, such asSimplexNoise.instanceseed- a seed for the INoise
-
addNoise
public static void addNoise(float[] substance, int width, int height, float multiplier, INoise noise, float z, long seed) Simply adds the result of a noise call, multiplied by the given multiplier, to each point in substance. Modifies substance in-place.- Parameters:
substance- as produced by initialize; will be modified!width- the width of the substance array; should be consistent throughout callsheight- the height of the substance array; should be consistent throughout callsmultiplier- multiplied with each noise call, so noise (usually too significant) can have its effect reducednoise- an INoise instance, such asSimplexNoise.instancez- a z position to be given to the Noise3D along with a point's x and yseed- a seed for the INoise
-
normalize
public static void normalize(float[] substance) Finds the highest and lowest values in the substance array and modifies the whole array so the lowest and highest values are contracted or expanded to -1.0 and 1.0, respectively, and other values change commensurately.- Parameters:
substance- a substance array, as produced by initialize, will be modified!
-
reshape
public static float[][] reshape(int width, int height, float[] substance) Makes a new 2D float array with the given width and height, using the given substance array for contents.- Parameters:
width- the width of the 2D array to produce; must be 1 or greaterheight- the height of the 2D array to produce; must be 1 or greatersubstance- a substance array as produced by initialize and modified by step- Returns:
- a new 2D float array with the contents of substance and the requested size
-
fill
public static void fill(float[][] target, float[] substance) Modifies target in-place so it is filled with as much data as possible from substance.- Parameters:
target- a non-null, non-empty 2D float array; will be modifiedsubstance- a substance array as produced by initialize and modified by step
-