Joshua Moerman
14 years ago
4 changed files with 132 additions and 143 deletions
@ -1,134 +0,0 @@ |
|||
#include "../Logger.hpp" |
|||
#include <fstream> |
|||
#include <cmath> |
|||
#include <cstdlib> |
|||
#include <cassert> |
|||
|
|||
#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(const 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_in) const { |
|||
std::string filename = filename_in; |
|||
filename += ".png"; |
|||
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"); |
|||
return; |
|||
} |
|||
} |
|||
|
|||
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.c_str()); |
|||
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.0; |
|||
//break;
|
|||
} |
|||
case 1: { |
|||
g = (pow(norm_value, power[c]*2.0))*3.0; |
|||
//break;
|
|||
} |
|||
case 2: { |
|||
b = (pow(norm_value, power[c]*3.0))*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.c_str()); |
|||
pngFile->close(); |
|||
|
|||
LogMoreInfo("File written"); |
|||
} |
Reference in new issue