#include "../Logger.hpp" #include #include #include #include #include "../pngwriter/pngwriter.h" #include "PNG.hpp" PNG::PNG(unsigned int width, unsigned int height, unsigned int num_colors): Canvas(2), width(width), height(height), num_colors(num_colors), v(0) { int_array = new unsigned int[width*height*num_colors]; assert(int_array != NULL); clear(); LogDebug("New Canvas\n"); } void PNG::clear() { for ( unsigned int i = 0; i < width*height*num_colors; i++ ) { int_array[i] = 0; } } void PNG::plot(double * position) { const double& x = position[0]; const double& y = position[1]; const unsigned int x_int = x*width + width*.5; const unsigned int y_int = y*width + height*.5; const unsigned int index = x_int + width * y_int; if(x_int < width && y_int < height) { int_array[index]++; } } /* I/O functions */ void PNG::output_file(const char * filename){ unsigned int * max_int = new unsigned int[num_colors]; double * power = new double[num_colors]; for ( unsigned int i = 0; i < num_colors; i++ ) { max_int[i] = 0; double cumulative = 0; unsigned int n = 0; for ( unsigned int j = 0; j < width*height; j++) { if ( max_int[i] < int_array[j+i*width*height] ) { max_int[i] = int_array[j+i*width*height]; } if ( int_array[j+i*width*height] ) { cumulative += int_array[j+i*width*height]; n++; } } if ( n > 100 ) { const double average = cumulative / (double)n; power[i] = -2.5/log(average/(double)max_int[i]); if ( power[i] < 0 ) power[i] = 1; } else { power[i] = 1; } if ( n <= 10 ) { LogInfo("not enough data\n"); } } const double vibrancy = 2.0; double averagePower = 0; for ( unsigned int i = 0; i < num_colors; i++ ) { averagePower += power[i]; } averagePower /= (double)num_colors; for ( unsigned int i = 0; i < num_colors; i++ ) { power[i] = vibrancy*power[i] + (1.0 - vibrancy)*averagePower; } pngwriter * pngFile = new pngwriter(width, height, 0.0, filename); pngFile->setcompressionlevel(9); pngFile->settext("Attractor", "Joshua Moerman", "A awesome attractor", "AwesomeAttractor"); for ( unsigned int x = 0; x < width; x++ ) { for ( unsigned int y = 0; y < height; y++ ) { double r = 0.0; double g = 0.0; double b = 0.0; for ( unsigned int c = 0; c < num_colors; c++ ) { const double norm_value = (double)int_array[x + y*width + c*width*height]/max_int[c]; switch(c){ case 0: { r = (pow(norm_value, power[c]))*3.5; break; } case 1: { g = (pow(norm_value, power[c]))*3.0; break; } case 2: { b = (pow(norm_value, power[c]))*3.0; break; } default: break; } } //pngwriter clips values for me pngFile->plot(x, y, r, g, b); } } delete[] max_int; delete[] power; LogInfo("Writing %s\n", filename); std::ofstream file(filename); if ( !file ) { LogError("Couldn't write to file"); } pngFile->close(); LogMoreInfo("File written"); }