/// <summary> /// Ridged multi-fractal /// </summary> /// <param name="x">Initial x coordinate</param> /// <param name="y">Initial y coordinate</param> /// <param name="freq">Frequency</param> /// <param name="numOctaves">Number of octaves</param> /// <param name="persistence">Persistence</param> /// <param name="basis">Basis function. Generates values between 0 and 1</param> /// <returns>Returns the generated fractal value between 0 and 1</returns> public static float RidgedFractal( float x, float y, float freq, int numOctaves, float persistence, Basis2dFunction basis ) { float offset = 1.0f; float signal = Math.Abs( basis( x, y ) ); signal = offset - signal; // invert and translate (note that "offset" should be ~= 1.0) signal *= signal; // square the signal, to increase "sharpness" of ridges float result = signal; float gain = 1.8f; float exp = 1; float max = 1; for ( int octave = 1; octave < numOctaves; ++octave ) { x *= freq; y *= freq; float weight = Utils.Clamp( signal * gain, 0, 1 ); signal = offset - Math.Abs( basis( x, y ) ); signal *= signal; signal *= weight; max += 1.0f / exp; result += signal / exp; exp *= freq; } return ( result / max ); }
/// <summary> /// Simple fractal /// </summary> /// <param name="x">Initial x coordinate</param> /// <param name="y">Initial y coordinate</param> /// <param name="freq">Frequency</param> /// <param name="numOctaves">Number of octaves</param> /// <param name="persistence">Persistence</param> /// <param name="basis">Basis function. Generates values between 0 and 1</param> /// <returns>Returns the generated fractal value between 0 and 1</returns> public static float SimpleFractal( float x, float y, float freq, int numOctaves, float persistence, Basis2dFunction basis ) { float amp = 1; float total = 0; float max = 0; for ( int octave = 0; octave < numOctaves; ++octave ) { total += basis( x, y ) * amp; max += amp; amp *= persistence; x *= freq; y *= freq; } return ( total + max ) / ( max * 2 ); }
/// <summary> /// Tiles a 2d function /// </summary> private float Tiled2dFunction( float x, float y, Basis2dFunction basis ) { x = Utils.Wrap( x, m_StartX, m_StartX + m_Width ); y = Utils.Wrap( y, m_StartY, m_StartY + m_Height ); float wrapX = x - m_Width; float wrapY = y - m_Height; float fX = x - m_StartX; float fY = y - m_StartY; float invX = m_Width - fX; float invY = m_Height - fY; float v0 = basis( x, y ) * invX * invY; float v1 = basis( wrapX, y ) * fX * invY; float v2 = basis( wrapX, wrapY ) * fX * fY; float v3 = basis( x, wrapY ) * invX * fY; return ( v0 + v1 + v2 + v3 ) * m_InvWH; }