#include #define TRUE 1 #define FALSE 0 typedef struct { double x; double y; double z; } Vector; /* * Procedural fBm evaluated at "point"; returns value stored in "value". * * Copyright 1994 F. Kenton Musgrave * * Parameters: * ``H'' is the fractal increment parameter * ``lacunarity'' is the gap between successive frequencies * ``octaves'' is the number of frequencies in the fBm */ double fBm( Vector point, double H, double lacunarity, double octaves ) { double value, frequency, remainder, Noise3(); int i; static int first = TRUE; static double *exponent_array; /* precompute and store spectral weights */ if ( first ) { /* seize required memory for exponent_array */ exponent_array = (double *)malloc( (octaves+1) * sizeof(double) ); frequency = 1.0; for (i=0; i<=octaves; i++) { /* compute weight for each frequency */ exponent_array[i] = pow( frequency, -H ); frequency *= lacunarity; } first = FALSE; } value = 0.0; /* initialize vars to proper values */ frequency = 1.0; /* inner loop of spectral construction */ for (i=0; i 1.0 ) weight = 1.0; /* get next higher frequency */ signal = ( Noise3( point ) + offset ) * exponent_array[i]; /* add it in, weighted by previous freq's local value */ result += weight * signal; /* update the (monotonically decreasing) weighting value */ /* (this is why H must specify a high fractal dimension) */ weight *= signal; /* increase frequency */ point.x *= lacunarity; point.y *= lacunarity; point.z *= lacunarity; } /* for */ /* take care of remainder in ``octaves'' */ remainder = octaves - (int)octaves; if ( remainder ) /* ``i'' and spatial freq. are preset in loop above */ result += remainder * Noise3( point ) * exponent_array[i]; return( result ); } /* HybridMultifractal() */ /* Ridged multifractal terrain model. * * Copyright 1994 F. Kenton Musgrave * * Some good parameter values to start with: * * H: 1.0 * offset: 1.0 * gain: 2.0 */ double RidgedMultifractal( Vector point, double H, double lacunarity, double octaves, double offset, double gain ) { double result, frequency, signal, weight, Noise3(); int i; static int first = TRUE; static double *exponent_array; /* precompute and store spectral weights */ if ( first ) { /* seize required memory for exponent_array */ exponent_array = (double *)malloc( (octaves+1) * sizeof(double) ); frequency = 1.0; for (i=0; i<=octaves; i++) { /* compute weight for each frequency */ exponent_array[i] = pow( frequency, -H ); frequency *= lacunarity; } first = FALSE; } /* get first octave */ signal = Noise3( point ); /* get absolute value of signal (this creates the ridges) */ if ( signal < 0.0 ) signal = -signal; /* invert and translate (note that "offset" should be ~= 1.0) */ signal = offset - signal; /* square the signal, to increase "sharpness" of ridges */ signal *= signal; /* assign initial values */ result = signal; weight = 1.0; for( i=1; i 1.0 ) weight = 1.0; if ( weight < 0.0 ) weight = 0.0; signal = Noise3( point ); if ( signal < 0.0 ) signal = -signal; signal = offset - signal; signal *= signal; /* weight the contribution */ signal *= weight; result += signal * exponent_array[i]; } return( result ); } /* RidgedMultifractal() */