indexing description: "Things used in all perlin noise procedures" author: "" date: "$Date$" revision: "$Revision$" deferred class EM_PERLIN_NOISE feature make is -- Set some default values do set_num_of_octaves (3) set_persistence (0.5) if (interpolator = void) then set_interpolator(create {EM_COSINE_INTERPOLATOR}) end random_size := 256 create random_array.make(0, random_size) create perm_array.make(0, random_size) set_seed(12345) end num_of_octaves: INTEGER set_num_of_octaves(a_num_of_octaves: INTEGER) is -- set the number of octaves that should be computed require valid_num_of_octaves: a_num_of_octaves >= 1 do num_of_octaves := a_num_of_octaves compute_noise_factor end persistence: DOUBLE set_persistence(a_persistence: DOUBLE) is -- Set the persistense for procedure require valid_persistence: a_persistence >= 0.0 and a_persistence <= 1.0 do persistence := a_persistence compute_noise_factor end set_seed (a_seed: INTEGER) is -- set the seed for perlin noise local random: RANDOM i: INTEGER do create random.set_seed(a_seed) from i := 0 until i >= random_array.count loop random.forth random_array.put ((random.item \\ random_size) / random_size, i) random.forth perm_array.put (random.item \\ random_size, i) i := i + 1 end end set_interpolator(an_interpolator: EM_INTERPOLATOR) is -- Set the interpolator to be used do interpolator := an_interpolator end feature {NONE} interpolator: EM_INTERPOLATOR compute_noise_factor is -- Compute the largest noise depending on num_of_octaves and persistence -- and from that the noise_factor. -- This is used to normalize the noise between 0.0 and 1.0 local sum_of_amplitudes: DOUBLE i: INTEGER do from i := 0 until i >= num_of_octaves loop sum_of_amplitudes := sum_of_amplitudes + (persistence ^ i.to_double) i := i + 1 end noise_factor := (1.0 / sum_of_amplitudes) end noise_factor: DOUBLE feature {NONE} -- Randomness random_array: ARRAY[DOUBLE] perm_array: ARRAY[INTEGER] -- Array used to permute values random_size: INTEGER feature {NONE} modulo(a_number: INTEGER; a_modulo: INTEGER): INTEGER is -- compute a valid (postive) modulo -- return 'number' if modulo is 0 do if a_modulo = 0 then Result := a_number else Result := ((a_number \\ a_modulo) + a_modulo) \\ a_modulo end ensure return_number_when_modulo_0: a_modulo = 0 implies Result = a_number result_in_range: a_modulo /= 0 implies Result >= 0 and Result < a_modulo end invariant interpolator_set: interpolator /= void noise_factor_computed: noise_factor /= 0 valid_num_of_octaves: num_of_octaves >= 1 valid_persistence: persistence >= 0.0 and persistence <= 1.0 random_size_set: random_size >= 0 random_array_created: random_array /= void perm_array_created: perm_array /= void end