From 3309bd91d50a5310e8dd22a056c1926f49b727be Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Sun, 19 Jan 2025 11:01:54 +0100 Subject: [PATCH] [orx-noise] Add generated and verified documentation --- orx-noise/src/commonMain/kotlin/Cell.kt | 19 ++ orx-noise/src/commonMain/kotlin/Fractal.kt | 281 +++++++++++++++++- .../src/commonMain/kotlin/GaussianRandom.kt | 40 +++ orx-noise/src/commonMain/kotlin/GradCoord.kt | 45 +++ .../src/commonMain/kotlin/GradientPerturb.kt | 53 ++++ .../src/commonMain/kotlin/Interpolation.kt | 28 ++ orx-noise/src/commonMain/kotlin/Polar.kt | 12 - orx-noise/src/commonMain/kotlin/ShapeNoise.kt | 13 +- .../src/commonMain/kotlin/SimplexNoise2D.kt | 16 +- .../src/commonMain/kotlin/SimplexNoise3D.kt | 16 + .../src/commonMain/kotlin/SimplexNoise4D.kt | 40 +++ .../src/commonMain/kotlin/UniformRandom.kt | 191 ++++++++++++ orx-noise/src/commonMain/kotlin/shapes/Box.kt | 13 + .../src/commonMain/kotlin/shapes/Circle.kt | 11 +- .../src/commonMain/kotlin/shapes/Rectangle.kt | 13 + .../src/commonMain/kotlin/shapes/Triangle.kt | 32 +- 16 files changed, 792 insertions(+), 31 deletions(-) diff --git a/orx-noise/src/commonMain/kotlin/Cell.kt b/orx-noise/src/commonMain/kotlin/Cell.kt index 09b4c6736..caf84225a 100644 --- a/orx-noise/src/commonMain/kotlin/Cell.kt +++ b/orx-noise/src/commonMain/kotlin/Cell.kt @@ -3,6 +3,16 @@ package org.openrndr.extra.noise import org.openrndr.math.Vector2 import org.openrndr.math.Vector3 +/** + * Represents a 2D array of pre-defined normalized Vector2 values often used + * in algorithms requiring pseudo-random or structured deterministic value sets. + * + * Each `Vector2` instance inside the array constitutes X and Y components + * that are normalized or constrained to a specific range. + * + * This array may serve as a set of offsets, noise gradients, or lookup values + * for computational geometry, randomization, or procedural generation tasks. + */ val Cell2D = arrayOf( Vector2(-0.4313539279, 0.1281943404), Vector2(-0.1733316799, 0.415278375), Vector2(-0.2821957395, -0.3505218461), Vector2(-0.2806473808, 0.3517627718), Vector2(0.3125508975, -0.3237467165), Vector2(0.3383018443, -0.2967353402), Vector2(-0.4393982022, -0.09710417025), Vector2(-0.4460443703, -0.05953502905), Vector2(-0.302223039, 0.3334085102), Vector2(-0.212681052, -0.3965687458), Vector2(-0.2991156529, 0.3361990872), Vector2(0.2293323691, 0.3871778202), Vector2(0.4475439151, -0.04695150755), Vector2(0.1777518, 0.41340573), Vector2(0.1688522499, -0.4171197882), Vector2(-0.0976597166, 0.4392750616), @@ -37,6 +47,15 @@ val Cell2D = arrayOf( Vector2(0.1475103971, -0.4251360756), Vector2(0.09258030352, 0.4403735771), Vector2(-0.1589664637, -0.4209865359), Vector2(0.2482445008, 0.3753327428), Vector2(0.4383624232, -0.1016778537), Vector2(0.06242802956, 0.4456486745), Vector2(0.2846591015, -0.3485243118), Vector2(-0.344202744, -0.2898697484), Vector2(0.1198188883, -0.4337550392), Vector2(-0.243590703, 0.3783696201), Vector2(0.2958191174, -0.3391033025), Vector2(-0.1164007991, 0.4346847754), Vector2(0.1274037151, -0.4315881062), Vector2(0.368047306, 0.2589231171), Vector2(0.2451436949, 0.3773652989), Vector2(-0.4314509715, 0.12786735)) +/** + * `Cell3D` represents a predefined 3-dimensional grid or lattice of points in space, where each point + * is represented as a `Vector3` object containing three coordinates (x, y, z). These coordinates are used + * for various computational purposes such as procedural generation, cell-based simulations, or spatial analysis. + * + * The points in `Cell3D` are statically defined and may represent offsets, directions, or specific positions + * within a system. The choice of values implies a structure or pattern that can be applied to systems utilizing + * a 3D grid or space representation. + */ val Cell3D = arrayOf( Vector3(0.1453787434, -0.4149781685, -0.0956981749), Vector3(-0.01242829687, -0.1457918398, -0.4255470325), Vector3(0.2877979582, -0.02606483451, -0.3449535616), Vector3(-0.07732986802, 0.2377094325, 0.3741848704), Vector3(0.1107205875, -0.3552302079, -0.2530858567), Vector3(0.2755209141, 0.2640521179, -0.238463215), Vector3(0.294168941, 0.1526064594, 0.3044271714), Vector3(0.4000921098, -0.2034056362, 0.03244149937), Vector3(-0.1697304074, 0.3970864695, -0.1265461359), Vector3(-0.1483224484, -0.3859694688, 0.1775613147), Vector3(0.2623596946, -0.2354852944, 0.2796677792), Vector3(-0.2709003183, 0.3505271138, -0.07901746678), Vector3(-0.03516550699, 0.3885234328, 0.2243054374), Vector3(-0.1267712655, 0.1920044036, 0.3867342179), Vector3(0.02952021915, 0.4409685861, 0.08470692262), Vector3(-0.2806854217, -0.266996757, 0.2289725438), diff --git a/orx-noise/src/commonMain/kotlin/Fractal.kt b/orx-noise/src/commonMain/kotlin/Fractal.kt index 4a1ebb888..a781a8c7c 100644 --- a/orx-noise/src/commonMain/kotlin/Fractal.kt +++ b/orx-noise/src/commonMain/kotlin/Fractal.kt @@ -5,12 +5,38 @@ import org.openrndr.math.Vector3 import org.openrndr.math.Vector4 import kotlin.math.abs +/** + * Generates a fractal Brownian motion (fbm) value based on the provided noise function. + * + * @param seed The seed value for the noise function, used to ensure consistent output for the same inputs. + * @param position The 4D vector representing the coordinates for evaluating noise. + * @param noise A function that evaluates 4D noise based on a seed and coordinates (x, y, z, w). + * @param octaves The number of noise layers to combine. Higher values produce more detailed noise patterns. + * @param lacunarity The frequency multiplier for each successive octave. + * @param gain The amplitude multiplier for each successive octave. + * + * @return A Double value representing the combined noise, with frequency and amplitude adjusted per octave. + */ inline fun fbm( seed: Int, position: Vector4, crossinline noise: (Int, Double, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 ) = fbm(seed, position.x, position.y, position.z, position.w, noise, octaves, lacunarity, gain) +/** + * Computes fractal Brownian motion (fBm) using the given noise function. + * + * @param seed An integer seed that initializes the noise generation. + * @param x The x-coordinate for the initial noise function. + * @param y The y-coordinate for the initial noise function. + * @param z The z-coordinate for the initial noise function. + * @param w The w-coordinate for the initial noise function. + * @param noise A higher-order function that generates noise based on the seed and coordinate inputs. + * @param octaves The number of iterations to apply the noise function for calculating fBm. Default is 8. + * @param lacunarity The frequency multiplier applied at each octave. Default is 0.5. + * @param gain The amplitude multiplier applied at each octave. Default is 0.5. + * @return The resultant fractal Brownian motion value as a Double. + */ inline fun fbm( seed: Int, x: Double, @@ -40,12 +66,39 @@ inline fun fbm( return sum } +/** + * Computes fractal Brownian motion (fBm) at a specific 3D position using a given noise function. + * + * @param seed The base seed for the noise function, used to initialize the random sequence. + * @param position The 3D position at which to evaluate the noise. + * @param noise A lambda function that generates noise based on the seed and 3D coordinates. + * @param octaves The number of iterations to compute the fBm. Defaults to 8. + * @param lacunarity Controls the frequency of successive octaves. Defaults to 0.5. + * @param gain Controls the amplitude of successive octaves. Defaults to 0.5. + * @return A Double representing the computed fractal Brownian motion value at the given position. + */ inline fun fbm( seed: Int, position: Vector3, crossinline noise: (Int, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 ) = fbm(seed, position.x, position.y, position.z, noise, octaves, lacunarity, gain) +/** + * Computes fractional Brownian motion (fBm) for a given seed, coordinates, and noise function. + * + * fBm is a procedural noise function that generates continuous, fractal-like patterns by + * combining multiple octaves of noise at different frequencies and amplitudes. + * + * @param seed The base seed value for the noise function. + * @param x The x-coordinate in the noise space. + * @param y The y-coordinate in the noise space. + * @param z The z-coordinate in the noise space. + * @param noise A function that generates noise values given a seed and coordinates x, y, z. + * @param octaves The number of noise octaves to combine. Defaults to 8. + * @param lacunarity The factor by which the frequency is increased for each octave. Defaults to 0.5. + * @param gain The factor by which the amplitude is decreased for each octave. Defaults to 0.5. + * @return The computed fBm value as a Double. + */ inline fun fbm( seed: Int, x: Double, y: Double, z: Double, crossinline noise: (Int, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 @@ -66,12 +119,36 @@ inline fun fbm( return sum } +/** + * Computes a fractal Brownian motion (FBM) value for a given 2D position using the provided noise function. + * + * @param seed The base seed for the noise function. + * @param position The 2D vector representing the position in space. + * @param noise A function that generates noise values, taking the seed, x-coordinate, and y-coordinate as inputs. + * @param octaves The number of layers of noise to generate. Defaults to 8. + * @param lacunarity The frequency multiplier for each layer of noise. Defaults to 0.5. + * @param gain The amplitude multiplier for each layer of noise. Defaults to 0.5. + * @return The computed FBM value for the given inputs. + */ inline fun fbm( seed: Int, position: Vector2, crossinline noise: (Int, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 ) = fbm(seed, position.x, position.y, noise, octaves, lacunarity, gain) +/** + * Generates fractional Brownian motion (fBm) using a base noise function. + * fBm is a technique to produce fractal-like procedural textures or terrains. + * + * @param seed Seed value for the noise function to ensure reproducibility. + * @param x The x-coordinate input for the noise function. + * @param y The y-coordinate input for the noise function. + * @param noise A base noise function that takes a seed, x, and y, and returns a noise value. + * @param octaves The number of noise layers (also referred to as octaves) to combine. Default is 8. + * @param lacunarity The frequency multiplier for each successive octave. Default is 0.5. + * @param gain The amplitude multiplier for each successive octave. Default is 0.5. + * @return The resulting fractional Brownian motion value. + */ inline fun fbm( seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 @@ -90,6 +167,17 @@ inline fun fbm( return sum } +/** + * Computes the fractional Brownian motion (FBM) value for a given input using a specified noise function. + * + * @param seed The seed value to initialize the noise function. + * @param x The input value for which the FBM is calculated. + * @param noise The noise function that generates noise values based on the seed and input. + * @param octaves The number of successive noise layers to combine. Default is 8. + * @param lacunarity The factor by which the frequency increases for each successive octave. Default is 0.5. + * @param gain The factor by which the amplitude decreases for each successive octave. Default is 0.5. + * @return The computed FBM value as a Double. + */ inline fun fbm( seed: Int, x: Double, crossinline noise: (Int, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 @@ -106,7 +194,7 @@ inline fun fbm( return sum } -inline fun fbmFunc1D( +internal inline fun fbmFunc1D( crossinline noise: (Int, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, @@ -117,7 +205,7 @@ inline fun fbmFunc1D( } } -inline fun fbmFunc2D( +internal inline fun fbmFunc2D( crossinline noise: (Int, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, @@ -128,7 +216,7 @@ inline fun fbmFunc2D( } } -inline fun fbmFunc3D( +internal inline fun fbmFunc3D( crossinline noise: (Int, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, @@ -139,7 +227,7 @@ inline fun fbmFunc3D( } } -inline fun fbmFunc4D( +internal inline fun fbmFunc4D( crossinline noise: (Int, Double, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, @@ -150,6 +238,17 @@ inline fun fbmFunc4D( } } +/** + * Generates a 4D Billow noise value, which is a type of fractal noise that emphasizes the absolute value of noise layers. + * + * @param seed The seed value to initialize the noise generator. + * @param position The 4D position vector (x, y, z, w) where the noise will be sampled. + * @param noise A function that represents the noise generation algorithm. Accepts the seed and 4D coordinates as input. + * @param octaves The number of noise layers applied to produce the final output. Defaults to 8. + * @param lacunarity The frequency multiplier for each successive octave. Defaults to 0.5. + * @param gain The amplitude multiplier for each successive octave. Defaults to 0.5. + * @return The resulting 4D Billow noise value. + */ inline fun billow( seed: Int, position: Vector4, crossinline noise: (Int, Double, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 @@ -158,6 +257,20 @@ inline fun billow( position.z, position.w, noise, octaves, lacunarity, gain ) +/** + * Generates a 4D billow noise value, which is a type of fractal noise that emphasizes the absolute value of noise layers. + * + * @param seed The seed value to initialize the noise generation. + * @param x The x-coordinate in the noise space. + * @param y The y-coordinate in the noise space. + * @param z The z-coordinate in the noise space. + * @param w The w-coordinate in the noise space. + * @param noise A function that generates the base noise value given a seed and coordinates. + * @param octaves The number of noise layers to combine. Default is 8. + * @param lacunarity The factor by which the frequency of each octave is scaled. Default is 0.5. + * @param gain The factor by which the amplitude of each octave is scaled. Default is 0.5. + * @return A `Double` representing the combined billow noise value based on the input parameters. + */ inline fun billow( seed: Int, x: Double, @@ -187,12 +300,40 @@ inline fun billow( return sum } +/** + * Generates a 3D Billow noise value, which is a type of fractal noise that emphasizes the absolute value of noise layers. + * + * @param seed The seed value for the noise function to ensure deterministic results. + * @param position A 3D vector representing the position for which the noise is calculated. + * @param noise A function that generates 3D noise given a seed and coordinates. + * @param octaves The number of layers of noise applied for detail (default is 8). + * @param lacunarity The frequency multiplier for successive noise layers (default is 0.5). + * @param gain The amplitude multiplier for successive noise layers (default is 0.5). + * @return The resultant billow noise value at the specified position. + */ inline fun billow( seed: Int, position: Vector3, crossinline noise: (Int, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 ) = billow(seed, position.x, position.y, position.z, noise, octaves, lacunarity, gain) +/** + * Generates a fractal noise pattern using the Billow algorithm. + * + * The Billow algorithm is a variation of the Perlin/simplex noise pattern, but it produces ridged + * patterns by taking the absolute value of the noise. This method combines multiple layers of noise + * (octaves) to produce a fractal appearance. + * + * @param seed The initial seed for the noise generation. Used as a basis for reproducibility. + * @param x The x-coordinate of the point to generate noise for. + * @param y The y-coordinate of the point to generate noise for. + * @param z The z-coordinate of the point to generate noise for. + * @param noise A function that takes a seed and three coordinates (x, y, z) and generates a noise value for that point. + * @param octaves The number of noise layers to combine. Default value is 8. + * @param lacunarity The scaling factor for the input coordinates between octaves. Higher values increase detail. Default value is 0.5. + * @param gain The amplitude reduction factor between octaves. Lower values reduce the influence of higher octaves. Default value is 0.5. + * @return A Double representing the fractal noise value at the specified coordinates using the Billow algorithm. + */ inline fun billow( seed: Int, x: Double, y: Double, z: Double, crossinline noise: (Int, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 @@ -213,12 +354,35 @@ inline fun billow( return sum } +/** + * Generates a 2D Billow noise value, which is a type of fractal noise that emphasizes the absolute value of noise layers. + * + * @param seed The seed for the noise function, used to generate repeatable patterns. + * @param position A 2D vector representing the coordinates at which noise is generated. + * @param noise A function that computes noise for a given seed and coordinates (x, y). + * @param octaves The number of noise layers to combine. Higher values provide more detail. Default is 8. + * @param lacunarity The frequency multiplier for successive noise layers. Default is 0.5. + * @param gain The amplitude multiplier for successive noise layers. Default is 0.5. + * @return A combined noise value for the specified position. + */ inline fun billow( seed: Int, position: Vector2, crossinline noise: (Int, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 ) = billow(seed, position.x, position.y, noise, octaves, lacunarity, gain) +/** + * Generates a 2D Billow noise value, which is a type of fractal noise that emphasizes the absolute value of noise layers. + * + * @param seed An integer seed value used to initialize the noise generation. + * @param x The x-coordinate for the noise generation. + * @param y The y-coordinate for the noise generation. + * @param noise A function that generates noise values given a seed and coordinates. + * @param octaves The number of iterations to perform to calculate the noise. Default is 8. + * @param lacunarity A multiplier applied to the coordinates at each octave to adjust frequency. Default is 0.5. + * @param gain A multiplier applied to the amplitude at each octave to adjust magnitude. Default is 0.5. + * @return The computed billow noise value as a Double. + */ inline fun billow( seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 @@ -237,6 +401,17 @@ inline fun billow( return sum } +/** + * Generates a Billow noise value, which is a type of fractal noise that emphasizes the absolute value of noise layers. + * + * @param seed The initial seed value used for noise generation. + * @param x The input value, typically representing a point in space or time. + * @param noise A function that generates noise based on the given seed and x value. + * @param octaves The number of layers of noise to generate. Higher values result in more detail. Defaults to 8. + * @param lacunarity The factor by which the frequency of the noise increases with each octave. Defaults to 0.5. + * @param gain The factor by which the amplitude of the noise decreases with each octave. Defaults to 0.5. + * @return A Double value representing the generated fractal noise. + */ inline fun billow( seed: Int, x: Double, crossinline noise: (Int, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 @@ -253,7 +428,7 @@ inline fun billow( return sum } -inline fun billowFunc1D( +internal inline fun billowFunc1D( crossinline noise: (Int, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, @@ -264,7 +439,7 @@ inline fun billowFunc1D( } } -inline fun billowFunc2D( +internal inline fun billowFunc2D( crossinline noise: (Int, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, @@ -275,7 +450,7 @@ inline fun billowFunc2D( } } -inline fun billowFunc3D( +internal inline fun billowFunc3D( crossinline noise: (Int, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, @@ -286,7 +461,7 @@ inline fun billowFunc3D( } } -inline fun billowFunc4D( +internal inline fun billowFunc4D( crossinline noise: (Int, Double, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, @@ -297,12 +472,36 @@ inline fun billowFunc4D( } } +/** + * Generates a 4D rigid multi-octave noise value based on the provided parameters and noise function. + * + * @param seed A base value used to seed the noise function. + * @param position A 4D vector specifying the coordinates (x, y, z, w) of the input point. + * @param noise A callback function that generates a noise value based on the given parameters: seed, x, y, z, and w. + * @param octaves The number of noise layers (octaves) to combine to achieve the rigid appearance. Defaults to 8. + * @param lacunarity The factor by which the frequency increases between successive octaves. Defaults to 0.5. + * @param gain The factor by which the amplitude decreases between successive octaves. Defaults to 0.5. + */ inline fun rigid( seed: Int, position: Vector4, crossinline noise: (Int, Double, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 ) = rigid(seed, position.x, position.y, position.z, position.w, noise, octaves, lacunarity, gain) +/** + * Generates a 4D rigid multi-octave noise value based on the provided parameters and noise function. + * + * @param seed A base value used to seed the noise function. + * @param x The x-coordinate of the input point. + * @param y The y-coordinate of the input point. + * @param z The z-coordinate of the input point. + * @param w The w-coordinate of the input point. + * @param noise A callback function that generates a noise value based on the given parameters: seed, x, y, z, and w. + * @param octaves The number of noise layers (octaves) to combine to achieve the rigid appearance. Defaults to 8. + * @param lacunarity The factor by which the frequency increases between successive octaves. Defaults to 0.5. + * @param gain The factor by which the amplitude decreases between successive octaves. Defaults to 0.5. + * @return A double precision value representing the computed rigid multi-octave noise. + */ inline fun rigid( seed: Int, x: Double, @@ -332,12 +531,36 @@ inline fun rigid( return sum } +/** + * Computes a multi-octave rigid noise value for a given position. + * + * @param seed The seed value for the noise generation. + * @param position A 3D vector representing the spatial coordinates. + * @param noise A function for generating noise, taking seed and three Double coordinates (x, y, z). + * @param octaves The number of noise octaves to compute. Defaults to 8. + * @param lacunarity The frequency multiplier between successive octaves. Defaults to 0.5. + * @param gain The amplitude multiplier between successive octaves. Defaults to 0.5. + * @return The computed rigid noise value. + */ inline fun rigid( seed: Int, position: Vector3, crossinline noise: (Int, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 ) = rigid(seed, position.x, position.y, position.z, noise, octaves, lacunarity, gain) +/** + * Generates a rigid multi-fractal noise value based on the given parameters. + * + * @param seed The seed value for the noise generation. + * @param x The x-coordinate of the point for noise calculation. + * @param y The y-coordinate of the point for noise calculation. + * @param z The z-coordinate of the point for noise calculation. + * @param noise A function that generates noise values based on the given seed and coordinates. + * @param octaves The number of iterations or layers to apply for generating the noise. Default is 8. + * @param lacunarity The frequency multiplier for each octave. Default is 0.5. + * @param gain The amplitude multiplier for each octave. Default is 0.5. + * @return The computed rigid multi-fractal noise value. + */ inline fun rigid( seed: Int, x: Double, y: Double, z: Double, crossinline noise: (Int, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 @@ -358,12 +581,35 @@ inline fun rigid( return sum } +/** + * Computes a value based on a rigid multi-fractal noise function using a 2D position. + * + * @param seed The seed value for the noise function. + * @param position The 2D vector representing the position for the noise function. + * @param noise A higher-order function that generates noise values based on a seed, x-coordinate, and y-coordinate. + * @param octaves The number of iterations to compute the rigid fractal noise, default is 8. + * @param lacunarity The frequency multiplier for each octave, default is 0.5. + * @param gain The amplitude multiplier for each octave, default is 0.5. + * @return The computed rigid fractal noise value. + */ inline fun rigid( seed: Int, position: Vector2, crossinline noise: (Int, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 ) = rigid(seed, position.x, position.y, noise, octaves, lacunarity, gain) +/** + * Computes a value based on a rigid multi-fractal noise function. + * + * @param seed The seed value for the noise function. + * @param x The x-coordinate for the noise function. + * @param y The y-coordinate for the noise function. + * @param noise A higher-order function that generates noise values based on a seed, x, and y. + * @param octaves The number of iterations to compute the rigid fractal noise, default is 8. + * @param lacunarity The frequency multiplier for each octave, default is 0.5. + * @param gain The amplitude multiplier for each octave, default is 0.5. + * @return The computed rigid fractal noise value. + */ inline fun rigid( seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 @@ -382,6 +628,17 @@ inline fun rigid( return sum } +/** + * Generates a rigid noise value using fractional Brownian motion (fBm) by combining multiple layers of noise. + * + * @param seed An integer value used to seed the noise generation for reproducibility. + * @param x The input coordinate for which the noise value is computed. + * @param noise A function that generates the base noise value, taking an integer seed and a double coordinate as input. + * @param octaves The number of layers of noise to combine. Default is 8. + * @param lacunarity The factor by which the frequency increases for each subsequent layer of noise. Default is 0.5. + * @param gain The factor by which the amplitude decreases for each subsequent layer of noise. Default is 0.5. + * @return A double value representing the computed rigid noise value. + */ inline fun rigid( seed: Int, x: Double, crossinline noise: (Int, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5 @@ -398,7 +655,7 @@ inline fun rigid( return sum } -inline fun rigidFunc1D( +internal inline fun rigidFunc1D( crossinline noise: (Int, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, @@ -409,7 +666,7 @@ inline fun rigidFunc1D( } } -inline fun rigidFunc2D( +internal inline fun rigidFunc2D( crossinline noise: (Int, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, @@ -420,7 +677,7 @@ inline fun rigidFunc2D( } } -inline fun rigidFunc3D( +internal inline fun rigidFunc3D( crossinline noise: (Int, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, @@ -431,7 +688,7 @@ inline fun rigidFunc3D( } } -inline fun rigidFunc4D( +internal inline fun rigidFunc4D( crossinline noise: (Int, Double, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, diff --git a/orx-noise/src/commonMain/kotlin/GaussianRandom.kt b/orx-noise/src/commonMain/kotlin/GaussianRandom.kt index e00ac7a2a..550bfa06b 100644 --- a/orx-noise/src/commonMain/kotlin/GaussianRandom.kt +++ b/orx-noise/src/commonMain/kotlin/GaussianRandom.kt @@ -7,6 +7,14 @@ import kotlin.math.ln import kotlin.math.sqrt import kotlin.random.Random +/** + * Generates a random number following a Gaussian (normal) distribution. + * + * @param mean The mean of the Gaussian distribution. Defaults to 0.0. + * @param deviation The standard deviation of the Gaussian distribution. Defaults to 1.0. + * @param random The random number generator to use. Defaults to Random.Default. + * @return A random number sampled from the specified Gaussian distribution. + */ fun gaussian(mean: Double = 0.0, deviation: Double = 1.0, random: Random = Random.Default): Double { var v1: Double var v2: Double @@ -21,20 +29,52 @@ fun gaussian(mean: Double = 0.0, deviation: Double = 1.0, random: Random = Rando return v1 * multiplier * deviation + mean } +/** + * Generates a random number following a Gaussian (normal) distribution. + * + * @param mean The mean of the Gaussian distribution. Defaults to 0.0. + * @param deviation The standard deviation of the Gaussian distribution. Defaults to 1.0. + * @param random The random number generator to use. Defaults to Random.Default. + * @return A random number sampled from the specified Gaussian distribution. + */ fun Double.Companion.gaussian( mean: Double = 0.0, deviation: Double = 1.0, random: Random = Random.Default ): Double = org.openrndr.extra.noise.gaussian(mean, deviation, random) +/** + * Generates a random 2D vector with components sampled from independent Gaussian (normal) distributions. + * + * @param mean The mean vector of the Gaussian distributions for the x and y components. Defaults to Vector2.ZERO. + * @param deviation The standard deviation vector of the Gaussian distributions for the x and y components. Defaults to Vector2.ONE. + * @param random The random number generator to use. Defaults to Random.Default. + * @return A 2D vector with components sampled from their respective Gaussian distributions. + */ fun Vector2.Companion.gaussian(mean: Vector2 = Vector2.ZERO, deviation: Vector2 = Vector2.ONE, random: Random = Random.Default): Vector2 { return Vector2(gaussian(mean.x, deviation.x, random), gaussian(mean.y, deviation.y, random)) } +/** + * Generates a random Vector3 following a Gaussian (normal) distribution. + * + * @param mean The mean vector for the Gaussian distribution. Defaults to Vector3.ZERO. + * @param deviation The standard deviation vector for the Gaussian distribution. Defaults to Vector3.ONE. + * @param random The random number generator to use. Defaults to Random.Default. + * @return A random Vector3 sampled from the specified Gaussian distribution. + */ fun Vector3.Companion.gaussian(mean: Vector3 = Vector3.ZERO, deviation: Vector3 = Vector3.ONE, random: Random = Random.Default): Vector3 { return Vector3(gaussian(mean.x, deviation.x, random), gaussian(mean.y, deviation.y, random), gaussian(mean.z, deviation.z, random)) } +/** + * Generates a random `Vector4` where each component is sampled independently from a Gaussian (normal) distribution. + * + * @param mean A `Vector4` representing the mean of the distribution for each component. Defaults to `Vector4.ZERO`. + * @param deviation A `Vector4` representing the standard deviation of the distribution for each component. Defaults to `Vector4.ONE`. + * @param random The random number generator to use. Defaults to `Random.Default`. + * @return A `Vector4` where each component is a random number sampled from the specified Gaussian distribution. + */ fun Vector4.Companion.gaussian(mean: Vector4 = Vector4.ZERO, deviation: Vector4 = Vector4.ONE, random: Random = Random.Default): Vector4 { return Vector4(gaussian(mean.x, deviation.x, random), gaussian(mean.y, deviation.y, random), gaussian(mean.z, deviation.z, random), gaussian(mean.w, deviation.w, random)) } diff --git a/orx-noise/src/commonMain/kotlin/GradCoord.kt b/orx-noise/src/commonMain/kotlin/GradCoord.kt index 4cbe0ce28..38f8d7e1e 100644 --- a/orx-noise/src/commonMain/kotlin/GradCoord.kt +++ b/orx-noise/src/commonMain/kotlin/GradCoord.kt @@ -19,6 +19,16 @@ private val GRAD_3D = arrayOf( Vector3(0.0, 1.0, 1.0), Vector3(0.0, -1.0, 1.0), Vector3(0.0, 1.0, -1.0), Vector3(0.0, -1.0, -1.0), Vector3(1.0, 1.0, 0.0), Vector3(0.0, -1.0, 1.0), Vector3(-1.0, 1.0, 0.0), Vector3(0.0, -1.0, -1.0)) +/** + * Computes the dot product of a gradient vector and a distance vector in 2D space. + * + * @param seed The seed value used for hashing and determining the gradient vector. + * @param x The x-coordinate in grid space used for hashing. + * @param y The y-coordinate in grid space used for hashing. + * @param xd The x component of the distance vector. + * @param yd The y component of the distance vector. + * @return The dot product of the gradient vector and the distance vector. + */ fun gradCoord2D(seed: Int, x: Int, y: Int, xd: Double, yd: Double): Double { val hash = uhash2D(seed, x, y) @@ -27,6 +37,18 @@ fun gradCoord2D(seed: Int, x: Int, y: Int, xd: Double, yd: Double): Double { return xd * x1 + yd * y1 } +/** + * Computes a gradient dot-product noise value for 3D coordinates based on the given seed and position inputs. + * + * @param seed The seed value used to generate the pseudo-random gradient. + * @param x The x-coordinate of the position in 3D space. + * @param y The y-coordinate of the position in 3D space. + * @param z The z-coordinate of the position in 3D space. + * @param xd The x-offset or displacement in 3D space. + * @param yd The y-offset or displacement in 3D space. + * @param zd The z-offset or displacement in 3D space. + * @return The computed gradient dot-product noise value as a Double. + */ fun gradCoord3D(seed: Int, x: Int, y: Int, z: Int, xd: Double, yd: Double, zd: Double): Double { val hash = uhash3D(seed, x, y, z) @@ -35,6 +57,20 @@ fun gradCoord3D(seed: Int, x: Int, y: Int, z: Int, xd: Double, yd: Double, zd: D return xd * g.x + yd * g.y + zd * g.z } +/** + * Computes a gradient coordinate value in 4D space based on the provided inputs. + * + * @param seed An integer seed value used to initialize the hash function. + * @param x The x-coordinate as an integer. + * @param y The y-coordinate as an integer. + * @param z The z-coordinate as an integer. + * @param w The w-coordinate as an integer. + * @param xd The x-offset as a double. + * @param yd The y-offset as a double. + * @param zd The z-offset as a double. + * @param wd The w-offset as a double. + * @return A double value representing the calculated gradient coordinate in 4D space. + */ fun gradCoord4D(seed: Int, x: Int, y: Int, z: Int, w: Int, xd: Double, yd: Double, zd: Double, wd: Double): Double { val hash = (uhash4D(seed, x, y, z, w) and 31U).toInt() @@ -64,6 +100,15 @@ fun gradCoord4D(seed: Int, x: Int, y: Int, z: Int, w: Int, xd: Double, yd: Doubl return (if (hash and 4 == 0) -a else a) + (if (hash and 2 == 0) -b else b) + if (hash and 1 == 0) -c else c } +/** + * Generates a pseudo-random value based on the input seed and 3D coordinates. + * + * @param seed The base seed value used for pseudo-random generation. + * @param x The x-coordinate in the 3D space. + * @param y The y-coordinate in the 3D space. + * @param z The z-coordinate in the 3D space. + * @return A pseudo-random double value calculated using the seed and coordinates. + */ fun valCoord3D(seed: Int, x: Int, y: Int, z: Int): Double { var n = seed n = n xor X_PRIME * x diff --git a/orx-noise/src/commonMain/kotlin/GradientPerturb.kt b/orx-noise/src/commonMain/kotlin/GradientPerturb.kt index 2bedc8fda..5faa66285 100644 --- a/orx-noise/src/commonMain/kotlin/GradientPerturb.kt +++ b/orx-noise/src/commonMain/kotlin/GradientPerturb.kt @@ -4,6 +4,23 @@ import org.openrndr.math.Vector2 import org.openrndr.math.Vector3 import org.openrndr.math.mix +/** + * Applies fractal gradient perturbation to a 3D position vector. + * + * This method perturbs the input position vector using a fractal noise pattern based on multiple + * octaves of gradient noise. It combines parameters such as amplitude, frequency, lacunarity, and gain + * to control the noise characteristics, while supporting custom interpolation. + * + * @param seed The initial seed value to generate the noise. + * @param amplitude The initial magnitude of the displacement during the perturbation. + * @param frequency The base frequency for the noise generation. + * @param lacunarity The frequency multiplier between successive octaves. + * @param gain The amplitude multiplier between successive octaves. + * @param octaves The number of noise layers (octaves) to combine in the fractal calculation. + * @param position The input 3D vector representing the position to perturb. + * @param interpolator A function to apply smooth interpolation, typically used for gradient noise transitions. + * @return The perturbed 3D position vector after applying the fractal gradient perturbation. + */ fun gradientPerturbFractal( seed: Int, amplitude: Double = 1.0, frequency: Double = 2.0, lacunarity: Double = 2.0, gain: Double = 0.5, @@ -24,6 +41,17 @@ fun gradientPerturbFractal( return p } +/** + * Perturbs a position vector in 3D space by applying a gradient noise algorithm. + * + * @param seed The seed value used for generating deterministic patterns. + * @param amplitude The amplitude of the perturbation, which controls the scale of displacement. + * @param frequency The frequency of the perturbation, which determines the scale of the noise. + * @param position The original position vector to be perturbed. + * @param interpolator The interpolation function used to smooth the noise transitions, + * defaulting to the quintic function. + * @return A new position vector that has been perturbed by the gradient noise algorithm. + */ fun gradientPerturb( seed: Int, amplitude: Double, @@ -85,6 +113,21 @@ fun gradientPerturb( ) * amplitude } +/** + * Applies fractal gradient perturbation to the given position vector using the specified parameters. + * This method introduces multiple layers of noise to create a fractal effect by perturbing the position iteratively + * based on the number of octaves, frequency, and amplitude adjustments. + * + * @param seed An integer seed used to initialize the random number generator for noise generation. + * @param amplitude The initial amplitude of the perturbation. Higher values result in larger displacements. + * @param frequency The initial frequency of the noise. Higher values increase the density of the noise variation. + * @param lacunarity The rate at which the frequency increases with each octave. + * @param gain The rate at which the amplitude decreases with each octave. + * @param octaves The number of fractal noise layers to apply. More octaves increase detail. + * @param position A 2D vector representing the original point to be perturbed. + * @param interpolator A function that defines how to interpolate values smoothly. Defaults to the quintic function. + * @return A 2D vector representing the perturbed position after applying the fractal gradient noise. + */ fun gradientPerturbFractal( seed: Int, amplitude: Double = 1.0, frequency: Double = 2.0, lacunarity: Double = 2.0, gain: Double = 0.5, @@ -105,6 +148,16 @@ fun gradientPerturbFractal( return p } +/** + * Calculates a perturbed position based on gradient noise. + * + * @param seed An integer seed value used to initialize the pseudo-random number generator. + * @param amplitude A double value that determines the strength of the perturbation applied to the position. + * @param frequency A double value that defines how frequent the perturbation occurs in the space. + * @param position A 2D vector specifying the initial position to perturb. + * @param interpolator A function used for interpolation between gradient values, defaults to the quintic interpolation function. + * @return A 2D vector that represents the new perturbed position. + */ fun gradientPerturb( seed: Int, amplitude: Double, diff --git a/orx-noise/src/commonMain/kotlin/Interpolation.kt b/orx-noise/src/commonMain/kotlin/Interpolation.kt index 9d4d23266..f02089d55 100644 --- a/orx-noise/src/commonMain/kotlin/Interpolation.kt +++ b/orx-noise/src/commonMain/kotlin/Interpolation.kt @@ -1,13 +1,41 @@ package org.openrndr.extra.noise +/** + * Computes the Hermite interpolation function value for the given parameter. + * + * The Hermite interpolation ensures smooth transitions and is often used in + * animations or procedural generation to create a smooth curve between points. + * + * @param t A double value representing the parameter for the interpolation. + * It is usually expected to be in the range [0.0, 1.0]. + * @return The interpolated value based on the Hermite polynomial. + */ fun hermite(t: Double): Double { return t * t * (3 - 2 * t) } +/** + * Calculates the result of the quintic polynomial function, commonly used in smooth interpolation. + * + * The function is defined as t^3 * (t * (t * 6 - 15) + 10), where t is the input value. + * + * @param t The input value for which the quintic function is to be calculated. + * @return The result of the quintic polynomial for the given input value. + */ fun quintic(t: Double): Double { return t * t * t * (t * (t * 6 - 15) + 10) } +/** + * Computes the value of a cubic interpolation given control points and a parameter t. + * + * @param a The first control point. + * @param b The second control point. + * @param c The third control point. + * @param d The fourth control point. + * @param t The interpolation factor, typically between 0 and 1. + * @return The interpolated value at the given t. + */ fun cubic(a: Double, b: Double, c: Double, d: Double, t: Double): Double { val p = d - c - (a - b) return t * t * t * p + t * t * (a - b - p) + t * (c - a) + b diff --git a/orx-noise/src/commonMain/kotlin/Polar.kt b/orx-noise/src/commonMain/kotlin/Polar.kt index 60d37ba29..a497a58c7 100644 --- a/orx-noise/src/commonMain/kotlin/Polar.kt +++ b/orx-noise/src/commonMain/kotlin/Polar.kt @@ -64,15 +64,3 @@ fun ((Int, Double, Double) -> Double).fixedRadiusPolar( origin: Vector2 = Vector2.ZERO ): (Int, Double) -> Double = fixedRadiusPolarFunc(this, radius, origin) - - - -fun example() { - val polarFbmSimplex = polarFunc(noise = fbmFunc2D(noise = ::simplex)) - val polarBillowPerlin = polarFunc(noise = billowFunc2D(noise = ::perlin)) - - val polarFbmSimplexAlt = fbmFunc2D(noise = ::simplex).withPolarInput() - - val polarFbm = simplex2D.fbm().withPolarInput() - -} \ No newline at end of file diff --git a/orx-noise/src/commonMain/kotlin/ShapeNoise.kt b/orx-noise/src/commonMain/kotlin/ShapeNoise.kt index f7b21f77e..f7cd4dd17 100644 --- a/orx-noise/src/commonMain/kotlin/ShapeNoise.kt +++ b/orx-noise/src/commonMain/kotlin/ShapeNoise.kt @@ -8,15 +8,24 @@ import org.openrndr.shape.* import kotlin.random.Random /** - * Generates specified amount of random points that lie inside the [Shape]. + * Generates a list of uniformly distributed points within the shape provided by the ShapeProvider. * * @param pointCount The number of points to generate. - * @param random The [Random] number generator to use, defaults to [Random.Default]. + * @param random An optional random number generator to influence the distribution. + * @return A list of Vector2 objects representing the uniformly distributed points. */ fun ShapeProvider.uniform(pointCount: Int, random: Random = Random.Default): List { return shape.triangulation.uniform(pointCount, random) } +/** + * Generates a list of hashed points based on the shape's triangulation. + * + * @param pointCount The number of points to generate in the hashed result. + * @param seed The seed value used for randomization in the hashing process. + * @param x An additional parameter used in the hashing process to modify randomization. + * @return A list of vectors representing the hashed points. + */ fun ShapeProvider.hash(pointCount: Int, seed: Int, x: Int): List { return shape.triangulation.hash(pointCount, seed, x) } diff --git a/orx-noise/src/commonMain/kotlin/SimplexNoise2D.kt b/orx-noise/src/commonMain/kotlin/SimplexNoise2D.kt index 23b8f8eac..b14b0e93b 100644 --- a/orx-noise/src/commonMain/kotlin/SimplexNoise2D.kt +++ b/orx-noise/src/commonMain/kotlin/SimplexNoise2D.kt @@ -9,7 +9,14 @@ private const val G2 = (3.0 - SQRT3) / 6.0 fun simplex(seed: Int, position: Vector2): Double = simplex(seed, position.x, position.y) -//fun simplex2D(seed:Int, x:Double, y:Double) = simplex(seed, x, y) +/** + * Computes a 2D simplex noise value for given coordinates and seed. + * + * @param seed The seed value used for generating the noise. + * @param x The x-coordinate in 2D space for which the noise value is calculated. + * @param y The y-coordinate in 2D space for which the noise value is calculated. + * @return The 2D simplex noise value for the given coordinates and seed. + */ fun simplex(seed: Int, x: Double, y: Double): Double { var t = (x + y) * F2 val i = (x + t).fastFloor() @@ -70,6 +77,13 @@ val simplex2D: (Int, Double, Double) -> Double = ::simplex val simplex3D: (Int, Double, Double, Double) -> Double = ::simplex val simplex4D: (Int, Double, Double, Double) -> Double = ::simplex +/** + * Generates a 2D simplex noise vector based on the given seed and input position. + * + * @param seed The seed value used to generate deterministic noise. + * @param x The x-coordinate for the noise generation. + * @return A Vector2 object representing the 2D noise values at the given position. + */ fun Vector2.Companion.simplex(seed: Int, x: Double): Vector2 = Vector2( simplex(seed, x, 0.0, 0.0, 0.0), simplex(seed, 0.0, x + 31.3383, 0.0, 0.0) diff --git a/orx-noise/src/commonMain/kotlin/SimplexNoise3D.kt b/orx-noise/src/commonMain/kotlin/SimplexNoise3D.kt index 52da64e86..58a4e40ee 100644 --- a/orx-noise/src/commonMain/kotlin/SimplexNoise3D.kt +++ b/orx-noise/src/commonMain/kotlin/SimplexNoise3D.kt @@ -8,6 +8,15 @@ private const val G33 = G3 * 3 - 1 fun simplex(seed: Int, position: Vector3): Double = simplex(seed, position.x, position.y, position.z) +/** + * Computes a 3D simplex noise value for the given coordinates and seed. + * + * @param seed The seed value used for generating consistent noise values. + * @param x The x-coordinate of the point in 3D space. + * @param y The y-coordinate of the point in 3D space. + * @param z The z-coordinate of the point in 3D space. + * @return The computed 3D simplex noise value as a Double. + */ fun simplex(seed: Int, x: Double, y: Double, z: Double): Double { val t = (x + y + z) / 3.0 @@ -101,6 +110,13 @@ fun simplex(seed: Int, x: Double, y: Double, z: Double): Double { return 32 * (n0 + n1 + n2 + n3) } +/** + * Generates a 3D vector using simplex noise based on the given seed and x-coordinate. + * + * @param seed The seed value used for generating consistent noise values. + * @param x The x-coordinate of the point in 3D space to calculate the noise value. + * @return A 3D vector where each component is a noise value calculated based on the given seed and coordinate. + */ fun Vector3.Companion.simplex(seed: Int, x: Double): Vector3 = Vector3(simplex(seed, x, 0.0, 0.0), simplex(seed, 0.0, x + 31.3383, 0.0), simplex(seed, 0.0, 0.0, x - 483.23)) \ No newline at end of file diff --git a/orx-noise/src/commonMain/kotlin/SimplexNoise4D.kt b/orx-noise/src/commonMain/kotlin/SimplexNoise4D.kt index 62feece2a..28b929358 100644 --- a/orx-noise/src/commonMain/kotlin/SimplexNoise4D.kt +++ b/orx-noise/src/commonMain/kotlin/SimplexNoise4D.kt @@ -2,6 +2,21 @@ package org.openrndr.extra.noise import org.openrndr.math.Vector4 +/** + * A precomputed permutation table specifically designed for 4D Simplex noise. + * + * The `SIMPLEX_4D` byte array contains a sequence of small integers representing + * a predefined ordering used to optimize the generation of 4D Simplex noise. + * This table helps reduce computations by providing a consistent lookup + * for gradients and permutations in the algorithm. + * + * It is structured in such a way to align with the needs of gradient calculations + * and index wrapping, ensuring consistency and performance in Simplex noise generation. + * + * This array acts as a critical component in the implementation of 4D Simplex noise + * algorithms, supporting the reduction of redundant calculations while ensuring + * deterministic outputs. + */ private val SIMPLEX_4D = byteArrayOf( 0, 1, 2, 3, 0, 1, 3, 2, 0, 0, 0, 0, 0, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 2, 1, 3, 0, 0, 0, 0, 0, 3, 1, 2, 0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 0, @@ -16,9 +31,26 @@ private val SIMPLEX_4D = byteArrayOf( private const val F4 = ((2.23606797 - 1.0) / 4.0) private const val G4 = ((5.0 - 2.23606797) / 20.0) +/** + * Computes the 4D Simplex noise value at the given position and seed. + * + * @param seed A unique seed value used to generate the noise. Different seed values produce different noise patterns. + * @param position A 4D vector containing the (x, y, z, w) coordinates where the noise value should be computed. + * @return The computed noise value as a Double. + */ fun simplex(seed: Int, position: Vector4) = simplex(seed, position.x, position.y, position.z, position.w) +/** + * Generates a 4D Simplex noise value based on the given coordinates and seed. + * + * @param seed An integer used to initialize the noise generation. + * @param x The x-coordinate in 4D space. + * @param y The y-coordinate in 4D space. + * @param z The z-coordinate in 4D space. + * @param w The w-coordinate in 4D space. + * @return A double representing the calculated 4D Simplex noise value at the given coordinates. + */ fun simplex(seed: Int, x: Double, y: Double, z: Double, w: Double): Double { var t = (x + y + z + w) * F4 @@ -107,6 +139,14 @@ fun simplex(seed: Int, x: Double, y: Double, z: Double, w: Double): Double { return 27 * (n0 + n1 + n2 + n3 + n4) } +/** + * Generates a 4D vector using Simplex noise based on the given seed and 1D input. + * Each component of the vector is generated by shifting the input x-coordinate for different noise values. + * + * @param seed An integer used to initialize the noise generation process. + * @param x The x-coordinate for generating the Simplex noise in 4D space. + * @return A Vector4 where each component is a 4D Simplex noise value. + */ fun Vector4.Companion.simplex(seed: Int, x: Double): Vector4 = Vector4(simplex(seed, x, 0.0, 0.0, 0.0), simplex(seed, 0.0, x + 31.3383, 0.0, 0.0), simplex(seed, 0.0, 0.0, x - 483.23, 0.0), diff --git a/orx-noise/src/commonMain/kotlin/UniformRandom.kt b/orx-noise/src/commonMain/kotlin/UniformRandom.kt index 5747a02d4..7144ea46a 100644 --- a/orx-noise/src/commonMain/kotlin/UniformRandom.kt +++ b/orx-noise/src/commonMain/kotlin/UniformRandom.kt @@ -11,12 +11,28 @@ fun random( ) = (random.nextDouble() * (max - min)) + min +/** + * Generates a uniformly distributed random integer within the specified range. + * + * @param min The lower bound of the range (inclusive). Default is -1. + * @param max The upper bound of the range (exclusive). Default is 2. + * @param random An instance of Random to generate the random value. Default is Random.Default. + * @return A random integer value within the range [min, max). + */ fun Int.Companion.uniform( min: Int = -1, max: Int = 2, random: Random = Random.Default ) = (random.nextDouble() * (max - min)).toInt() + min +/** + * Generates a random double value within the specified range [min, max]. + * + * @param min The minimum value of the range (inclusive). Defaults to -1.0. + * @param max The maximum value of the range (exclusive). Defaults to 1.0. + * @param random The random number generator to use. Defaults to Random.Default. + * @return A randomly generated double value between [min, max]. + */ fun Double.Companion.uniform( min: Double = -1.0, max: Double = 1.0, random: Random = Random.Default @@ -29,6 +45,14 @@ fun Double.Companion.hash( ) = fhash1D(seed, x) * (max - min) + min +/** + * Generates a random 2D vector with each component uniformly distributed within the specified ranges. + * + * @param min The minimum values for the x and y components of the vector (inclusive). Defaults to Vector2(-1, -1). + * @param max The maximum values for the x and y components of the vector (exclusive). Defaults to Vector2(1, 1). + * @param random The random number generator to use. Defaults to Random.Default. + * @return A randomly generated Vector2 object with components within [min.x, max.x) and [min.y, max.y). + */ fun Vector2.Companion.uniform( min: Vector2 = -ONE, max: Vector2 = ONE, random: Random = Random.Default @@ -38,6 +62,14 @@ fun Vector2.Companion.uniform( Double.uniform(min.y, max.y, random) ) +/** + * Generates a hash-based 2D vector based on the provided seed, input value, and range constraints. + * + * @param seed An integer used to initialize the hash generation process, providing variability in the result. + * @param x The input value used as the basis for generating the hash values. + * @param min The minimum bounds for both components of the resulting vector. Defaults to -ONE. + * @param max The maximum bounds for both components of the resulting vector. Defaults to ONE. + */ fun Vector2.Companion.hash( seed: Int, x: Int, min: Vector2 = -ONE, max: Vector2 = ONE @@ -47,12 +79,28 @@ fun Vector2.Companion.hash( Double.hash(seed xor 0x7f7f7f7f, x, min.y, max.y) ) +/** + * Generates a random 2D vector with components uniformly distributed within the specified range. + * + * @param min The minimum value for both x and y components of the vector (inclusive). Default is -1.0. + * @param max The maximum value for both x and y components of the vector (exclusive). Default is 1.0. + * @param random The random number generator to use. Default is Random.Default. + * @return A randomly generated Vector2 object with both x and y components within the range [min, max). + */ fun Vector2.Companion.uniform( min: Double = -1.0, max: Double = 1.0, random: Random = Random.Default ) = Vector2.uniform(Vector2(min, min), Vector2(max, max), random) +/** + * Generates a 2D hash-based vector using specified seed, input value, and range bounds. + * + * @param seed An integer seed value for initializing the hash generation. + * @param x The numerical input value used for generating the hash. + * @param min The minimum value bound for both vector components. Defaults to -1.0. + * @param max The maximum value bound for both vector components. Defaults to 1.0. + */ fun Vector2.Companion.hash( seed: Int, x: Int, min: Double = -1.0, max: Double = 1.0, @@ -60,6 +108,13 @@ fun Vector2.Companion.hash( Vector2.hash(seed, x, Vector2(min, min), Vector2(max, max)) +/** + * Generates a random 2D vector uniformly distributed within the specified rectangular bounds. + * + * @param rect The rectangle within which the vector's components will be randomly generated. + * @param random The random number generator to use. Defaults to Random.Default. + * @return A randomly generated Vector2 object with components within the bounds of the specified rectangle. + */ fun Vector2.Companion.uniform( rect: Rectangle, random: Random = Random.Default @@ -69,6 +124,13 @@ fun Vector2.Companion.uniform( rect.corner + rect.dimensions, random ) +/** + * Generates a random `IntVector2` with each component within the specified ranges. + * + * @param min The minimum values for the x and y components of the vector. Default is `IntVector2(-1, -1)`. + * @param max The maximum exclusive values for the x and y components of the vector. Default is `IntVector2(2, 2)`. + * @param random The random number generator used to generate the values. Default is `Random.Default`. + */ fun IntVector2.Companion.uniform( min: IntVector2 = IntVector2(-1, -1), max: IntVector2 = IntVector2(2, 2), @@ -79,6 +141,14 @@ fun IntVector2.Companion.uniform( Int.uniform(min.y, max.y, random) ) +/** + * Generates a uniform random `IntVector2` within the specified range. + * + * @param min The minimum inclusive value for both components of the vector. Defaults to -1. + * @param max The maximum exclusive value for both components of the vector. Defaults to 2. + * @param random The random number generator to use. Defaults to `Random.Default`. + * @return A randomly generated `IntVector2` within the specified bounds. + */ fun IntVector2.Companion.uniform( min: Int = -1, max: Int = 2, random: Random = Random.Default @@ -88,6 +158,15 @@ fun IntVector2.Companion.uniform( IntVector2(max, max), random ) +/** + * Generates a random 2D vector uniformly distributed within a ring defined by the inner and outer radii. + * + * @param innerRadius The inner radius of the ring. Must be less than or equal to outerRadius. Default is 0.0. + * @param outerRadius The outer radius of the ring. Default is 1.0. + * @param random The random number generator to use. Default is Random.Default. + * @return A 2D vector uniformly distributed within the specified ring. + * @throws IllegalArgumentException If innerRadius is greater than outerRadius. + */ fun Vector2.Companion.uniformRing( innerRadius: Double = 0.0, outerRadius: Double = 1.0, @@ -118,6 +197,16 @@ fun Vector2.Companion.uniformRing( } } +/** + * Generates a list of `Vector2` instances, each initialized with random values within + * the specified range. + * + * @param count The number of `Vector2` instances to generate. + * @param min The minimum range for the random `Vector2` values. Defaults to `-ONE`. + * @param max The maximum range for the random `Vector2` values. Defaults to `ONE`. + * @param random The random number generator to use. Defaults to `Random.Default`. + * @return A list of randomly generated `Vector2` instances. + */ fun Vector2.Companion.uniforms( count: Int, min: Vector2 = -ONE, @@ -128,6 +217,14 @@ fun Vector2.Companion.uniforms( Vector2.uniform(min, max, random) } +/** + * Generates a list of uniformly distributed random points within a specified rectangular area. + * + * @param count The number of random points to generate. + * @param rect The rectangular area within which the points will be generated. + * @param random The random number generator to use for point generation. Defaults to [Random.Default]. + * @return A list of [Vector2] objects representing the generated random points. + */ fun Vector2.Companion.uniforms( count: Int, rect: Rectangle, @@ -135,6 +232,14 @@ fun Vector2.Companion.uniforms( ): List = List(count) { Vector2.uniform(rect, random) } +/** + * Generates an infinite sequence of random `Vector2` points uniformly distributed + * within the specified rectangle. + * + * @param rect The rectangle within which the random `Vector2` points will be generated. + * @param random The random number generator to use for generating points. Defaults to `Random.Default`. + * @return A sequence of `Vector2` points uniformly distributed within the specified rectangle. + */ fun Vector2.Companion.uniformSequence( rect: Rectangle, random: Random = Random.Default @@ -145,6 +250,15 @@ fun Vector2.Companion.uniformSequence( } } +/** + * Generates a list of 2D vectors uniformly distributed within a ring defined by the inner and outer radii. + * + * @param count The number of vectors to generate. + * @param innerRadius The inner radius of the ring. Must be less than or equal to outerRadius. Default is 0.0. + * @param outerRadius The outer radius of the ring. Default is 1.0. + * @param random The random number generator to use. Default is Random.Default. + * @return A list of 2D vectors uniformly distributed within the specified ring. + */ fun Vector2.Companion.uniformsRing( count: Int, innerRadius: Double = 0.0, outerRadius: Double = 1.0, @@ -154,9 +268,25 @@ fun Vector2.Companion.uniformsRing( Vector2.uniformRing(innerRadius, outerRadius, random) } +/** + * Generates a random vector with each component uniformly distributed between the specified minimum and maximum bounds. + * + * @param min The minimum bound for the vector components. Defaults to -1.0 for all components. + * @param max The maximum bound for the vector components. Defaults to 1.0 for all components. + * @param random The source of randomness. Defaults to the system default random generator. + * @return A random vector with each component uniformly distributed between the specified bounds. + */ fun Vector3.Companion.uniform(min: Double = -1.0, max: Double = 1.0, random: Random = Random.Default): Vector3 = Vector3.uniform(Vector3(min, min, min), Vector3(max, max, max), random) +/** + * Generates a random vector with components uniformly distributed between the specified minimum and maximum bounds. + * + * @param min The minimum bound for each component of the vector. Defaults to a vector with all components set to -1. + * @param max The maximum bound for each component of the vector. Defaults to a vector with all components set to 1. + * @param random The source of randomness. Defaults to the system default random generator. + * @return A random vector with components uniformly distributed between the specified bounds. + */ fun Vector3.Companion.uniform( min: Vector3 = -ONE, max: Vector3 = ONE, @@ -169,6 +299,15 @@ fun Vector3.Companion.uniform( ) } +/** + * Generates a random 3D vector within a uniform ring defined by the provided inner and outer radii. + * The ring resides in a 3D space, and vectors are uniformly distributed within the specified range. + * + * @param innerRadius The inner radius of the ring. Default is 0.0. + * @param outerRadius The outer radius of the ring. Default is 1.0. + * @param random The random number generator to be used for generating the vector. Default is Random.Default. + * @return A random 3D vector within the specified uniform ring. + */ fun Vector3.Companion.uniformRing( innerRadius: Double = 0.0, outerRadius: Double = 1.0, @@ -184,6 +323,15 @@ fun Vector3.Companion.uniformRing( } } +/** + * Generates a list of uniformly distributed random `Vector3` instances. + * + * @param count The number of `Vector3` instances to generate. + * @param min The minimum value for each component of the `Vector3`. Defaults to -1.0. + * @param max The maximum value for each component of the `Vector3`. Defaults to 1.0. + * @param random The random number generator to use. Defaults to `Random.Default`. + * @return A list of uniformly distributed random `Vector3` instances. + */ fun Vector3.Companion.uniforms( count: Int, min: Double = -1.0, @@ -195,6 +343,15 @@ fun Vector3.Companion.uniforms( } +/** + * Generates a list of uniformly distributed random `Vector3` instances. + * + * @param count The number of `Vector3` instances to generate. + * @param min The minimum bound for each `Vector3` component. Defaults to `-ONE`. + * @param max The maximum bound for each `Vector3` component. Defaults to `ONE`. + * @param random The random number generator used for generating components. Defaults to `Random.Default`. + * @return A list of uniformly distributed random `Vector3` instances. + */ fun Vector3.Companion.uniforms( count: Int, min: Vector3 = -ONE, @@ -205,6 +362,15 @@ fun Vector3.Companion.uniforms( Vector3.uniform(min, max, random) } +/** + * Generates a list of uniformly distributed random vectors within a ring defined by inner and outer radii. + * + * @param count The number of vectors to generate. + * @param innerRadius The inner radius of the ring. Defaults to 0.0. + * @param outerRadius The outer radius of the ring. Defaults to 1.0. + * @param random The random number generator to use. Defaults to Random.Default. + * @return A list of randomly generated vectors uniformly distributed within the ring. + */ fun Vector3.Companion.uniformsRing( count: Int, innerRadius: Double = 0.0, outerRadius: Double = 1.0, @@ -215,9 +381,26 @@ fun Vector3.Companion.uniformsRing( } +/** + * Generates a random 4-dimensional vector with each component sampled uniformly + * from a specified range between [min] and [max]. + * + * @param min The minimum value of the range for all components. Default is -1.0. + * @param max The maximum value of the range for all components. Default is 1.0. + * @param random The random number generator to use. Default is `Random.Default`. + * @return A `Vector4` instance with random components within the specified range. + */ fun Vector4.Companion.uniform(min: Double = -1.0, max: Double = 1.0, random: Random = Random.Default): Vector4 = Vector4.uniform(Vector4(min, min, min, min), Vector4(max, max, max, max), random) +/** + * Generates a random 4-dimensional vector where each component is uniformly distributed within the provided range. + * + * @param min The minimum values for each component of the vector. Defaults to -ONE. + * @param max The maximum values for each component of the vector. Defaults to ONE. + * @param random The random number generator to use. Defaults to Random.Default. + * @return A 4-dimensional vector with components uniformly distributed between the specified minimum and maximum values. + */ fun Vector4.Companion.uniform(min: Vector4 = -ONE, max: Vector4 = ONE, random: Random = Random.Default): Vector4 { return Vector4( Double.uniform(min.x, max.x, random), @@ -227,6 +410,14 @@ fun Vector4.Companion.uniform(min: Vector4 = -ONE, max: Vector4 = ONE, random: R ) } +/** + * Generates a uniformly distributed random 4D vector within a ring-shaped area defined by an inner and outer radius. + * + * @param innerRadius The minimum radius of the ring. Defaults to 0.0. + * @param outerRadius The maximum radius of the ring. Defaults to 1.0. + * @param random An instance of Random used to generate the random vector. Defaults to Random.Default. + * @return A random 4D vector within the specified ring. + */ fun Vector4.Companion.uniformRing( innerRadius: Double = 0.0, outerRadius: Double = 1.0, diff --git a/orx-noise/src/commonMain/kotlin/shapes/Box.kt b/orx-noise/src/commonMain/kotlin/shapes/Box.kt index 44eaa9f7b..d386bb706 100644 --- a/orx-noise/src/commonMain/kotlin/shapes/Box.kt +++ b/orx-noise/src/commonMain/kotlin/shapes/Box.kt @@ -5,6 +5,12 @@ import org.openrndr.math.Vector3 import org.openrndr.shape.Box import kotlin.random.Random +/** + * Generates a uniformly distributed random point inside the `Box`. + * + * @param random An optional random number generator to use. Defaults to `Random.Default`. + * @return A `Vector3` representing a random point within the `Box`. + */ fun Box.uniform(random: Random = Random.Default): Vector3 { val x = random.nextDouble() * width + corner.x val y = random.nextDouble() * height + corner.y @@ -12,6 +18,13 @@ fun Box.uniform(random: Random = Random.Default): Vector3 { return Vector3(x, y ,z) } +/** + * Generates a random point inside the boundary of the Box using a hash-based approach. + * + * @param seed An integer seed used for hashing to produce deterministic random results for a given seed. + * @param x An integer that acts as an additional input to the hash, allowing variation in the generated points. + * @return A Vector3 representing the random point within the Box, based on the provided seed and x. + */ fun Box.hash(seed: Int, x: Int): Vector3 { val ux = uhash11(seed.toUInt() + uhash11(x.toUInt())) val uy = uhash11(ux + x.toUInt()) diff --git a/orx-noise/src/commonMain/kotlin/shapes/Circle.kt b/orx-noise/src/commonMain/kotlin/shapes/Circle.kt index 20c817b08..b27bcb0eb 100644 --- a/orx-noise/src/commonMain/kotlin/shapes/Circle.kt +++ b/orx-noise/src/commonMain/kotlin/shapes/Circle.kt @@ -9,7 +9,11 @@ import kotlin.math.sqrt import kotlin.random.Random /** - * Generate a uniformly distributed random point inside [Circle] + * Generates a random point within the bounds of the `Circle` using a hash-based approach. + * + * @param seed An integer seed for the hash function, used to produce deterministic random results for the same seed. + * @param x An integer input to the hash function, adding further variation to the generated point. + * @return A `Vector2` representing a random point within the `Circle`, based on the provided `seed` and `x`. */ fun Circle.hash(seed: Int, x: Int): Vector2 { val r = radius * sqrt(fhash1D(seed, x)) @@ -18,7 +22,10 @@ fun Circle.hash(seed: Int, x: Int): Vector2 { } /** - * Generate a uniformly distributed random point inside [Circle] + * Generates a uniformly distributed random point within the `Circle`. + * + * @param random An optional random number generator to use. Defaults to `Random.Default`. + * @return A `Vector2` representing a random point within the `Circle`. */ fun Circle.uniform(random: Random = Random.Default): Vector2 { val r = radius * sqrt(random.nextDouble()) diff --git a/orx-noise/src/commonMain/kotlin/shapes/Rectangle.kt b/orx-noise/src/commonMain/kotlin/shapes/Rectangle.kt index fb33cb067..4e613812f 100644 --- a/orx-noise/src/commonMain/kotlin/shapes/Rectangle.kt +++ b/orx-noise/src/commonMain/kotlin/shapes/Rectangle.kt @@ -5,12 +5,25 @@ import org.openrndr.math.Vector2 import org.openrndr.shape.Rectangle import kotlin.random.Random +/** + * Generates a uniformly distributed random point within the `Rectangle`. + * + * @param random An optional random number generator to use. Defaults to `Random.Default`. + * @return A `Vector2` representing a random point within the `Rectangle`. + */ fun Rectangle.uniform(random: Random = Random.Default): Vector2 { val x = random.nextDouble() * width + corner.x val y = random.nextDouble() * height + corner.y return Vector2(x, y) } +/** + * Generates a random point within the bounds of the `Rectangle` using a hash-based approach. + * + * @param seed An integer seed for the hash function, used to produce deterministic random results for the same seed. + * @param x An integer input to the hash function, adding further variation to the generated point. + * @return A `Vector2` representing a random point within the `Rectangle`, based on the provided `seed` and `x`. + */ fun Rectangle.hash(seed: Int, x: Int): Vector2 { val ux = uhash11(seed.toUInt() + uhash11(x.toUInt())) val uy = uhash11(ux + x.toUInt()) diff --git a/orx-noise/src/commonMain/kotlin/shapes/Triangle.kt b/orx-noise/src/commonMain/kotlin/shapes/Triangle.kt index 7f317ebfd..30e97a16b 100644 --- a/orx-noise/src/commonMain/kotlin/shapes/Triangle.kt +++ b/orx-noise/src/commonMain/kotlin/shapes/Triangle.kt @@ -6,8 +6,13 @@ import org.openrndr.math.Vector2 import org.openrndr.shape.Triangle import kotlin.random.Random + /** - * Generate [count] uniform samples from a list of [Triangle]s + * Generates a list of 2D points distributed uniformly over a collection of triangles. + * + * @param count The number of random points to generate. + * @param random An optional random number generator to use. Defaults to `Random.Default`. + * @return A list of uniformly distributed 2D points over the triangles. */ fun List.uniform(count: Int, random: Random = Random.Default): List { val totalArea = this.sumOf { it.area } @@ -27,6 +32,16 @@ fun List.uniform(count: Int, random: Random = Random.Default): List.hash(count: Int, seed: Int = 0, x: Int = 0): List { val totalArea = this.sumOf { it.area } val randoms = (0 until count).map { @@ -45,12 +60,25 @@ fun List.hash(count: Int, seed: Int = 0, x: Int = 0): List { return result } -/** Generates a random point that lies inside the [Triangle]. */ + +/** + * Generates a uniformly distributed random point within the `Triangle`. + * + * @param random An optional random number generator to use. Defaults to `Random.Default`. + * @return A `Vector2` representing a random point within the `Triangle`. + */ fun Triangle.uniform(random: Random = Random.Default): Vector2 { return position(random.nextDouble(), random.nextDouble()) } +/** + * Generates a random point within the bounds of the `Triangle` using a hash-based approach. + * + * @param seed An integer seed for the hash function, used to produce deterministic random results for the same seed. + * @param x An integer input to the hash function, adding further variation to the generated point. + * @return A `Vector2` representing a random point within the `Triangle`, based on the provided `seed` and `x`. + */ fun Triangle.hash(seed: Int, x: Int): Vector2 { val u = fhash1D(seed, x) val v = fhash1D(seed, u.toRawBits().toInt() + x)