From 701faf6ece43ca24934e2b3ea8d8f591ea0cd746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Sun, 9 Jun 2013 14:56:45 +0200 Subject: [PATCH] Fixed noise range and normalization (with unit testing) --- src/rendering/noise.c | 17 +++------ src/testing/main.c | 2 ++ src/testing/test_noise.c | 78 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 src/testing/test_noise.c diff --git a/src/rendering/noise.c b/src/rendering/noise.c index 5525cc9..60b652f 100644 --- a/src/rendering/noise.c +++ b/src/rendering/noise.c @@ -202,17 +202,8 @@ void noiseValidate(NoiseGenerator* generator) generator->_max_value = generator->height_offset; for (x = 0; x < generator->level_count; x++) { - double min_value = generator->levels[x].minvalue; - double max_value = min_value + generator->levels[x].amplitude; - - if (min_value < generator->_min_value) - { - generator->_min_value = min_value; - } - if (max_value > generator->_max_value) - { - generator->_max_value = max_value; - } + generator->_min_value += generator->levels[x].minvalue; + generator->_max_value += generator->levels[x].minvalue + generator->levels[x].amplitude; } } @@ -394,14 +385,14 @@ void noiseNormalizeAmplitude(NoiseGenerator* generator, double minvalue, double for (level = 0; level < generator->level_count; level++) { - generator->levels[level].minvalue = minvalue + (generator->levels[level].minvalue - current_minvalue) * factor; + generator->levels[level].minvalue *= factor; generator->levels[level].amplitude *= factor; if (adjust_scaling) { generator->levels[level].wavelength *= factor; } } - /*generator->height_offset = minvalue + (generator->height_offset - current_minvalue) * factor;*/ + generator->height_offset = minvalue + (generator->height_offset - current_minvalue) * factor; noiseValidate(generator); } diff --git a/src/testing/main.c b/src/testing/main.c index d66edc4..78b74d9 100644 --- a/src/testing/main.c +++ b/src/testing/main.c @@ -6,6 +6,7 @@ extern void test_euclid_case(Suite* s); extern void test_camera_case(Suite* s); extern void test_clouds_case(Suite* s); +extern void test_noise_case(Suite* s); int main(int argc, char** argv) { @@ -18,6 +19,7 @@ int main(int argc, char** argv) test_euclid_case(s); test_camera_case(s); test_clouds_case(s); + test_noise_case(s); SRunner *sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); diff --git a/src/testing/test_noise.c b/src/testing/test_noise.c new file mode 100644 index 0000000..5ab413e --- /dev/null +++ b/src/testing/test_noise.c @@ -0,0 +1,78 @@ +#include "testing/common.h" + +#include "rendering/noise.h" + +START_TEST(test_noise_range) +{ + NoiseGenerator* noise; + double minvalue, maxvalue; + + noise = noiseCreateGenerator(); + + noiseAddLevelSimple(noise, 0.1, -1.0, 1.0); + noiseAddLevelSimple(noise, 0.2, -0.5, 0.2); + noiseAddLevelSimple(noise, 0.4, -0.3, 1.2); + noiseValidate(noise); + noiseGetRange(noise, &minvalue, &maxvalue); + + ck_assert_double_eq(minvalue, -1.8); + ck_assert_double_eq(maxvalue, 2.4); +} +END_TEST + +START_TEST(test_noise_normalize) +{ + int x; + NoiseGenerator* noise; + + noise = noiseCreateGenerator(); + + /* Symmetric case */ + noiseAddLevelsSimple(noise, 10, 1.0, -4.0, 4.0, 0.5); + noiseValidate(noise); + noiseNormalizeAmplitude(noise, -1.0, 1.0, 0); + for (x = 0; x < 1000; x++) + { + double value = noiseGet1DTotal(noise, 0.01 * (double)x); + ck_assert_double_in_range(value, -1.0, 1.0); + } + + /* Target center differs from current center */ + noiseClearLevels(noise); + noiseAddLevelsSimple(noise, 10, 1.0, -5.0, 5.0, 0.5); + noiseValidate(noise); + noiseNormalizeAmplitude(noise, 0.0, 1.0, 0); + for (x = 0; x < 1000; x++) + { + double value = noiseGet1DTotal(noise, 0.01 * (double)x); + ck_assert_double_in_range(value, 0.0, 1.0); + } + + /* Asymmetric range */ + noiseClearLevels(noise); + noiseAddLevelsSimple(noise, 10, 1.0, 0.0, 10.0, 0.0); + noiseValidate(noise); + noiseNormalizeAmplitude(noise, 0.0, 1.0, 0); + for (x = 0; x < 1000; x++) + { + double value = noiseGet1DTotal(noise, 0.01 * (double)x); + ck_assert_double_in_range(value, 0.0, 1.0); + } + + /* Complex asymmetric case */ + noiseClearLevels(noise); + noiseAddLevelsSimple(noise, 3, 1.0, -2.0, 8.0, 0.3); + noiseValidate(noise); + noiseNormalizeAmplitude(noise, -2.0, 4.0, 0.0); + for (x = 0; x < 1000; x++) + { + double value = noiseGet1DTotal(noise, 0.01 * (double)x); + ck_assert_double_in_range(value, -2.0, 4.0); + } + + noiseDeleteGenerator(noise); +} +END_TEST + +TEST_CASE(noise, test_noise_range, test_noise_normalize) +