unknown
14 years ago
8 changed files with 269 additions and 279 deletions
@ -1,241 +1,3 @@ |
|||||
#include "Logger.hpp" |
|
||||
#include <fstream> |
|
||||
#include <cmath> |
|
||||
#include <cstdlib> |
|
||||
#include <cassert> |
|
||||
|
|
||||
#include "pngwriter/pngwriter.h" |
|
||||
|
|
||||
#include "Canvas.hpp" |
#include "Canvas.hpp" |
||||
|
|
||||
|
// lol
|
||||
Canvas::Canvas(unsigned int width, unsigned int height, unsigned int num_colors): |
|
||||
dim(2), width(width), height(height), num_colors(num_colors), v(0) { |
|
||||
|
|
||||
int_array = new unsigned int[width*height*num_colors]; |
|
||||
size = new unsigned int[2]; |
|
||||
size[0] = width; |
|
||||
size[1] = height; |
|
||||
|
|
||||
assert(int_array != NULL); |
|
||||
|
|
||||
clear(); |
|
||||
|
|
||||
LogDebug("New Canvas\n"); |
|
||||
} |
|
||||
|
|
||||
void Canvas::clear() { |
|
||||
for ( unsigned int i = 0; i < width*height*num_colors; i++ ) { |
|
||||
int_array[i] = 0; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
//void Canvas::update_viewwindow() {
|
|
||||
//
|
|
||||
// //width and height of attractor
|
|
||||
// const double dx = xmax - xmin;
|
|
||||
// const double dy = ymax - ymin;
|
|
||||
//
|
|
||||
// //fix aspect ratio
|
|
||||
// if ( dx > dy * ((float)width / height) ) {
|
|
||||
// const double height2 = dx * ((float)height / width);
|
|
||||
// const double middle = 0.5 * (ymax + ymin);
|
|
||||
// ymax = middle + 0.5 * height2;
|
|
||||
// ymin = middle - 0.5 * height2;
|
|
||||
//
|
|
||||
// } else {
|
|
||||
// const double width2 = dy * ((float)width / height);
|
|
||||
// const double middle = 0.5 * (xmax + xmin);
|
|
||||
// xmax = middle + 0.5 * width2;
|
|
||||
// xmin = middle - 0.5 * width2;
|
|
||||
// }
|
|
||||
//
|
|
||||
// //add a 4% marge
|
|
||||
// xmin -= 0.02 * dx;
|
|
||||
// xmax += 0.02 * dx;
|
|
||||
// ymin -= 0.02 * dy;
|
|
||||
// ymax += 0.02 * dy;
|
|
||||
//
|
|
||||
// //constants for speed
|
|
||||
// constant1 = width / (xmax - xmin);
|
|
||||
// constant2 = height / (ymax - ymin);
|
|
||||
//}
|
|
||||
|
|
||||
void Canvas::plot(double x, double y) { |
|
||||
// gets x and y coordinate
|
|
||||
// ranges [-1, 1] and [-1, 1]
|
|
||||
// so how to do the aspect shiz, i don't know
|
|
||||
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]++; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void Canvas::plot(double x, double y, unsigned int c) { |
|
||||
// same as plot(double x, double y)
|
|
||||
// now with color control
|
|
||||
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 + width*height*c; |
|
||||
|
|
||||
if(x_int < width && y_int < height) { |
|
||||
int_array[index]++; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void Canvas::plot(double x, double y, unsigned int c, double intensity) { |
|
||||
// same as plot(double x, double y, unsigned int c)
|
|
||||
// but now uses the float array (not yet implemented
|
|
||||
} |
|
||||
|
|
||||
/*
|
|
||||
I/O functions |
|
||||
*/ |
|
||||
void Canvas::output() { |
|
||||
LogMoreInfo("Canvas: \n Dimensions: %d x %d x %d\n", width, height, num_colors); |
|
||||
} |
|
||||
|
|
||||
void Canvas::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"); |
|
||||
|
|
||||
} |
|
||||
|
|
||||
void Canvas::output_file(){ |
|
||||
char filename[50]; |
|
||||
time_t t = time(0); |
|
||||
struct tm* lt = localtime(&t); |
|
||||
int r = rand() % 10; |
|
||||
|
|
||||
sprintf(filename, "render/attractor_%04d-%02d-%02d_%02d-%02d-%02d-%01d.png", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, r); |
|
||||
|
|
||||
output_file(filename); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
void Canvas::output_raw(const char * filename){ |
|
||||
|
|
||||
std::ofstream outfile (filename, std::ofstream::binary); |
|
||||
|
|
||||
outfile.write(reinterpret_cast<char*>(int_array), sizeof(unsigned int)*width*height*num_colors); |
|
||||
|
|
||||
} |
|
||||
|
|
||||
void Canvas::output_raw(){ |
|
||||
char filename[52]; |
|
||||
time_t t = time(0); |
|
||||
struct tm* lt = localtime(&t); |
|
||||
int r = rand() % 10; |
|
||||
|
|
||||
sprintf(filename, "render/canv%dx%d_%04d-%02d-%02d_%02d-%02d-%02d-%01d.canv", width, height, lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, r); |
|
||||
|
|
||||
output_raw(filename); |
|
||||
} |
|
||||
|
|
||||
void Canvas::input_raw(const char * filename){ |
|
||||
std::ifstream infile(filename, std::ifstream::binary); |
|
||||
|
|
||||
if ( ! infile ) { |
|
||||
LogError("Could not read file %s", filename); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
infile.seekg (0, std::ios::end); |
|
||||
int length = infile.tellg(); |
|
||||
infile.seekg (0, std::ios::beg); |
|
||||
|
|
||||
LogDebug("Length: %d =? %d\n", length, static_cast<int>(width*height*num_colors*sizeof(unsigned int))); |
|
||||
|
|
||||
infile.read (reinterpret_cast<char*>(int_array), sizeof (unsigned int)*width*height*num_colors); |
|
||||
} |
|
||||
|
@ -0,0 +1,137 @@ |
|||||
|
#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(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"); |
||||
|
|
||||
|
} |
@ -0,0 +1,27 @@ |
|||||
|
#ifndef PNG_HPP |
||||
|
#define PNG_HPP |
||||
|
|
||||
|
#include "../Canvas.hpp" |
||||
|
|
||||
|
class PNG : public Canvas { |
||||
|
unsigned int width; |
||||
|
unsigned int height; |
||||
|
unsigned int num_colors; |
||||
|
|
||||
|
unsigned int * int_array; |
||||
|
|
||||
|
public: |
||||
|
|
||||
|
double v; |
||||
|
|
||||
|
PNG (unsigned int width, unsigned int height, unsigned int num_colors = 1); |
||||
|
|
||||
|
virtual void clear(); |
||||
|
virtual void plot (const double * normalizedPosition); |
||||
|
virtual void output_file (const char * filename) const; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
|
||||
|
#endif // PNG_HPP
|
||||
|
|
@ -0,0 +1,58 @@ |
|||||
|
#include "../Logger.hpp" |
||||
|
#include <fstream> |
||||
|
#include <cmath> |
||||
|
#include <cstdlib> |
||||
|
#include <cassert> |
||||
|
#include <algorithm> |
||||
|
#include <numeric> |
||||
|
#include <functional> |
||||
|
|
||||
|
#include "Raw.hpp" |
||||
|
|
||||
|
|
||||
|
Raw::Raw (const unsigned int dimension, const unsigned int* sizes_): |
||||
|
Canvas(dimension) { |
||||
|
|
||||
|
sizes = new unsigned int[dimension]; |
||||
|
assert(sizes != NULL); |
||||
|
std::copy(sizes_, sizes_ + dimension, sizes); |
||||
|
|
||||
|
sizesMultiplied = new unsigned int[dimension]; |
||||
|
assert(sizesMultiplied != NULL); |
||||
|
sizesMultiplied[0] = 1; |
||||
|
for ( unsigned int i = 1; i < dimension; ++i ) { |
||||
|
sizesMultiplied[i] = sizesMultiplied[i-1]*sizes[i-1]; |
||||
|
} |
||||
|
|
||||
|
arraySize = std::accumulate(sizes, sizes + dimension, multiplies<unsigned int>); |
||||
|
pixelArray = new unsigned int[arraySize]; |
||||
|
assert(pixelArray != NULL); |
||||
|
|
||||
|
clear(); |
||||
|
|
||||
|
LogDebug("New RawCanvas of dimension %d\n", dimension); |
||||
|
} |
||||
|
|
||||
|
void Raw::clear() { |
||||
|
std::fill_n(pixelArray, arraySize, 0); |
||||
|
} |
||||
|
|
||||
|
void Raw::plot(double * position) { |
||||
|
unsigned int index = 0; |
||||
|
for ( unsigned int i = 0; i < dimension; ++i ) { |
||||
|
index += (position[i]*sizes[i] + 0.5*sizes[i])*sizesMultiplied[i]; |
||||
|
} |
||||
|
|
||||
|
if(index < arraySize) { |
||||
|
int_array[index]++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
I/O functions |
||||
|
*/ |
||||
|
|
||||
|
void Raw::output_file(const char * filename){ |
||||
|
std::ofstream outfile (filename, std::ofstream::binary); |
||||
|
outfile.write(reinterpret_cast<char*>(int_array), sizeof(unsigned int)*width*height*num_colors); |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
#ifndef RAW_HPP |
||||
|
#define RAW_HPP |
||||
|
|
||||
|
#include "../Canvas.hpp" |
||||
|
|
||||
|
class Raw : public Canvas { |
||||
|
unsigned int * sizes; |
||||
|
unsigned int sizesMultiplied; |
||||
|
unsigned int * pixelArray; |
||||
|
unsigned int arraySize; |
||||
|
|
||||
|
public: |
||||
|
|
||||
|
Raw (const unsigned int dimension, const unsigned int* sizes); |
||||
|
|
||||
|
virtual void clear(); |
||||
|
virtual void plot (const double * normalizedPosition); |
||||
|
virtual void output_file (const char * filename) const; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
|
||||
|
#endif // RAW_HPP
|
||||
|
|
Reference in new issue