#include "bmp.h" #include "noise.h" #include #include #include #include #include // Generate comparison BMP showing both raw and uniform noise side by side void generate_comparison_bmp( const std::string &filename, int size, double scale, std::uint64_t seed, int octaves = 3, double persistence = 0.5 ) { // Create noise generators istd::PerlinNoise raw_noise(seed); istd::UniformPerlinNoise uniform_noise(seed); // Calibrate uniform noise uniform_noise.calibrate(scale, octaves, persistence); const int panel_width = size; const int gap = 10; const int total_width = panel_width * 2 + gap; BmpWriter bmp(total_width, size); // Fill gap with white for (int y = 0; y < size; ++y) { for (int x = panel_width; x < panel_width + gap; ++x) { bmp.set_pixel(x, y, 255, 255, 255); } } // Generate histograms for statistics std::vector raw_histogram(10, 0); std::vector uniform_histogram(10, 0); // Generate left panel (raw noise) for (int y = 0; y < size; ++y) { for (int x = 0; x < size; ++x) { double noise_value = raw_noise.octave_noise( x * scale, y * scale, octaves, persistence ); // Update histogram int bin = std::min(9, static_cast(noise_value * 10)); raw_histogram[bin]++; bmp.set_pixel_normalized(x, y, noise_value); } } // Generate right panel (uniform noise) int panel_offset = panel_width + gap; for (int y = 0; y < size; ++y) { for (int x = 0; x < size; ++x) { double noise_value = uniform_noise.uniform_noise(x, y); // Update histogram int bin = std::min(9, static_cast(noise_value * 10)); uniform_histogram[bin]++; bmp.set_pixel_normalized(panel_offset + x, y, noise_value); } } if (!bmp.save(filename)) { std::cerr << "Error: Could not save BMP file: " << filename << std::endl; return; } std::cout << "Noise comparison BMP generated: " << filename << std::endl; std::cout << "Size: " << size << "x" << size << " pixels per panel" << std::endl; std::cout << "Parameters: scale=" << scale << ", octaves=" << octaves << ", seed=" << seed << std::endl; // Print histogram comparison std::cout << "\nValue Distribution Analysis:\n"; std::cout << "Range | Raw Noise | Uniform Noise\n"; std::cout << "---------|-----------|--------------\n"; for (int i = 0; i < 10; ++i) { double range_start = i * 0.1; double range_end = (i + 1) * 0.1; std::cout << std::fixed << std::setprecision(1) << range_start << "-" << range_end << " | " << std::setw(9) << raw_histogram[i] << " | " << std::setw(12) << uniform_histogram[i] << "\n"; } } int main(int argc, char *argv[]) { // Default parameters std::uint64_t seed = 12345; std::string output_filename = "noise_comparison.bmp"; double scale = 0.08; int octaves = 3; double persistence = 0.5; // Parse command line arguments if (argc >= 2) { seed = std::strtoull(argv[1], nullptr, 10); } if (argc >= 3) { output_filename = argv[2]; } if (argc >= 4) { scale = std::strtod(argv[3], nullptr); } if (argc >= 5) { octaves = std::strtol(argv[4], nullptr, 10); } if (argc >= 6) { persistence = std::strtod(argv[5], nullptr); } if (argc == 1 || argc > 6) { std::cout << "Usage: " << argv[0] << " [seed] [output.bmp] [scale] [octaves] [persistence]\n"; std::cout << "Defaults: seed=12345, output=noise_comparison.bmp, " "scale=0.08, octaves=3, persistence=0.5\n"; std::cout << "This will generate a side-by-side comparison of raw vs " "uniform Perlin noise\n"; if (argc > 6) { return 1; } } std::cout << "Generating noise comparison (256x256 per panel)..." << std::endl; std::cout << "Parameters: seed=" << seed << ", scale=" << scale << ", octaves=" << octaves << ", persistence=" << persistence << std::endl; // Generate the comparison generate_comparison_bmp( output_filename, 256, scale, seed, octaves, persistence ); return 0; }