Package squidpony.squidmath
Class TuringPattern
java.lang.Object
squidpony.squidmath.TuringPattern
public class TuringPattern extends Object
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.
Created by Tommy Ettinger on 4/27/2017.
This class tries to provide a fairly raw API so different adjustments can be made on top of it.
Created by Tommy Ettinger on 4/27/2017.
-
Constructor Summary
Constructors Constructor Description TuringPattern()
-
Method Summary
Modifier and Type Method Description static void
addNoise(double[] substance, int width, int height, double multiplier, Noise.Noise2D noise, long seed)
Simply adds the result of a noise call, multiplied by the given multiplier, to each point in substance.static void
addNoise(double[] substance, int width, int height, double multiplier, Noise.Noise3D noise, double z, long seed)
Simply adds the result of a noise call, multiplied by the given multiplier, to each point in substance.static void
distort(int[][] offsets, int width, int height, Noise.Noise2D noise, long seed)
Alters the given offset information (as a jagged 2D int array) with the given Noise2D instance and seed.static void
distort(int[][] offsets, int width, int height, Noise.Noise3D noise, double 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.static void
fill(double[][] target, double[] substance)
Modifies target in-place so it is filled with as much data as possible from substance.static double[]
initialize(int width, int height)
Initializes a substance array that can be given to other static methods.static double[]
initialize(int width, int height, long seed)
Initializes a substance array that can be given to other static methods.static double[]
initialize(int width, int height, IRNG rng)
Initializes a substance array that can be given to other static methods.static double[]
initialize(int width, int height, Noise.Noise2D noise, long seed)
Initializes a substance array that can be given to other static methods.static double[]
initializeInto(double[] substance)
Refills a substance array that can be given to other static methods.static double[]
initializeInto(double[] substance, int width, int height, Noise.Noise2D noise, long seed)
Initializes a substance array that can be given to other static methods.static double[]
initializeInto(double[] substance, long seed)
Refills a substance array that can be given to other static methods.static double[]
initializeInto(double[] substance, IRNG rng)
Initializes a substance array that can be given to other static methods.static void
normalize(double[] 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, double 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, double 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, even if the array is final.static void
refit(double[] data)
Modifies the data parameter so no value in it is outside the range -1.0 inclusive to 1.0 exclusive.static double[][]
reshape(int width, int height, double[] substance)
Makes a new 2D double array with the given width and height, using the given substance array for contents.static void
step(double[] substance, int[][] activator, double activation, int[][] inhibitor, double inhibition)
Brings together the other methods to advance the substance simulation by one step, modifying substance in-place.static void
stepPartial(double[] substance, int[][] activator, double activation, int[][] inhibitor, double inhibition)
Computes the first part of a step, allowing other adjustments to be mixed in before finishing by callingnormalize(double[])
.
-
Constructor Details
-
TuringPattern
public TuringPattern()
-
-
Method Details
-
initialize
Initializes a substance array that can be given to other static methods. Uses very little 64-bit math, making it ideal for GWT.- 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 double array that represents a 2D array with random contents; should be given to other methods
-
initializeInto
Refills a substance array that can be given to other static methods. Uses very little 64-bit math, making it ideal for GWT.- Parameters:
substance
- a 1D double array that will be modified and filled with random values- Returns:
- substance, after modification; should be given to other methods
-
initialize
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 double array that represents a 2D array with random contents; should be given to other methods
-
initializeInto
Refills a substance array that can be given to other static methods.- Parameters:
substance
- a 1D double array that will be modified and filled with random valuesseed
- the long seed to use for the random contents- Returns:
- substance, after modification; should be given to other methods
-
initialize
Initializes a substance array that can be given to other static methods. Uses an RNG to produce long values that this turns into doubles 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 callsrng
- the random number generator responsible for producing random double values- Returns:
- a 1D double array that represents a 2D array with random contents; should be given to other methods
-
initializeInto
Initializes a substance array that can be given to other static methods. Uses an RNG to produce long values that this turns into doubles in the desired range (that is, -1.0 to 1.0).- Parameters:
substance
- a 1D double array that will be modified and filled with random valuesrng
- the random number generator responsible for producing random double values- Returns:
- a 1D double 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
- a Noise.Noise2D instance, such asSeededNoise.instance
seed
- the seed to use with the noise generator- Returns:
- a 1D double array that represents a 2D array with random contents; should be given to other methods
-
initializeInto
public static double[] initializeInto(double[] substance, int width, int height, Noise.Noise2D 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
- a Noise.Noise2D instance, such asSeededNoise.instance
seed
- the seed to use with the noise generator- Returns:
- a 1D double array that represents a 2D array with random contents; should be given to other methods
-
refit
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, though it probably will still work. 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 double array that will be modified in-place so all values in it will be between -1.0 and 1.0
-
offsetsCircleInto
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, even if the array is final.- Parameters:
offsets
- an offset information array that should have been produced byoffsetsCircle(int, int, double)
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(double[], int[][], double, int[][], double)
-
offsetsCircle
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(double[], int[][], double, int[][], double)
-
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, double)
; 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
- a Noise2D instance, such asSeededNoise.instance
, that will be used to alter offsetsseed
- a seed for the Noise2D
-
distort
public static void distort(int[][] offsets, int width, int height, Noise.Noise3D noise, double 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, double)
; 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
- a Noise3D instance, such asSeededNoise.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(double[] substance, int[][] activator, double activation, int[][] inhibitor, double 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(double[])
, and the activator and inhibitor should have been produced by calls to an offsets method likeoffsetsCircle(int, int, double)
, 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 double amount to use when the activator is dominant; should usually be positiveinhibitor
- as produced by an offsets methodinhibition
- the small double amount to use when the inhibitor is dominant; should usually be negative
-
stepPartial
public static void stepPartial(double[] substance, int[][] activator, double activation, int[][] inhibitor, double inhibition)Computes the first part of a step, allowing other adjustments to be mixed in before finishing by callingnormalize(double[])
. A sample adjustment would beaddNoise(double[], int, int, double, Noise.Noise2D, 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 double amount to use when the activator is dominant; should usually be positiveinhibitor
- as produced by an offsets methodinhibition
- the small double amount to use when the inhibitor is dominant; should usually be negative- See Also:
step, which is preferred to this method
-
addNoise
public static void addNoise(double[] substance, int width, int height, double multiplier, Noise.Noise2D 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
- a Noise2D instance, such asSeededNoise.instance
seed
- a seed for the Noise2D
-
addNoise
public static void addNoise(double[] substance, int width, int height, double multiplier, Noise.Noise3D noise, double 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
- a Noise3D instance, such asSeededNoise.instance
z
- a z position to be given to the Noise3D along with a point's x and yseed
- a seed for the Noise3D
-
normalize
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
Makes a new 2D double 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 double array with the contents of substance and the requested size
-
fill
Modifies target in-place so it is filled with as much data as possible from substance.- Parameters:
target
- a non-null, non-empty 2D double array; will be modified!substance
- a substance array as produced by initialize and modified by step
-