working version
This commit is contained in:
parent
d62df77b06
commit
9f0fae9640
9 changed files with 519 additions and 310 deletions
|
@ -7,6 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
42D0F93D146E8A95002B1025 /* libpng.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42D0F93C146E8A95002B1025 /* libpng.dylib */; };
|
||||
42D2E1221456175C00FBC16A /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42D2E1211456175C00FBC16A /* main.cpp */; };
|
||||
42D2E1241456175C00FBC16A /* AwesomeAttractorND.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 42D2E1231456175C00FBC16A /* AwesomeAttractorND.1 */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
@ -25,15 +26,19 @@
|
|||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
4235C47014655A4000C4E90F /* Vectors.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Vectors.hpp; sourceTree = "<group>"; };
|
||||
424F11B914643DD5005B8843 /* AttractorKernel.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AttractorKernel.hpp; sourceTree = "<group>"; };
|
||||
428EFECF145AF6E0001DBE1B /* Canvas.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Canvas.hpp; sourceTree = "<group>"; };
|
||||
428EFED4145AFAB4001DBE1B /* Tonemapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tonemapper.hpp; sourceTree = "<group>"; };
|
||||
42C2D1521461676B001BF28D /* Image.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Image.hpp; sourceTree = "<group>"; };
|
||||
42C2D1611461894E001BF28D /* Logging.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Logging.hpp; sourceTree = "<group>"; };
|
||||
42C2D1621461E562001BF28D /* array.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = array.hpp; sourceTree = "<group>"; };
|
||||
42D0F939146E7F6A002B1025 /* ImageFormatBMP.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatBMP.hpp; sourceTree = "<group>"; };
|
||||
42D0F93B146E805D002B1025 /* ImageFormatPNG.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatPNG.hpp; sourceTree = "<group>"; };
|
||||
42D0F93C146E8A95002B1025 /* libpng.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpng.dylib; path = usr/local/lib/libpng.dylib; sourceTree = SDKROOT; };
|
||||
42D2E11D1456175C00FBC16A /* AwesomeAttractorND */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AwesomeAttractorND; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
42D2E1211456175C00FBC16A /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
||||
42D2E1231456175C00FBC16A /* AwesomeAttractorND.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = AwesomeAttractorND.1; sourceTree = "<group>"; };
|
||||
42D2E12A1456176800FBC16A /* nd_array.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = nd_array.hpp; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -41,6 +46,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
42D0F93D146E8A95002B1025 /* libpng.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -50,6 +56,7 @@
|
|||
42D2E1121456175C00FBC16A = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
42D0F93C146E8A95002B1025 /* libpng.dylib */,
|
||||
42D2E1201456175C00FBC16A /* AwesomeAttractorND */,
|
||||
42D2E11E1456175C00FBC16A /* Products */,
|
||||
);
|
||||
|
@ -68,11 +75,14 @@
|
|||
children = (
|
||||
42D2E1211456175C00FBC16A /* main.cpp */,
|
||||
42C2D1611461894E001BF28D /* Logging.hpp */,
|
||||
42D2E12A1456176800FBC16A /* nd_array.hpp */,
|
||||
428EFECF145AF6E0001DBE1B /* Canvas.hpp */,
|
||||
42C2D1621461E562001BF28D /* array.hpp */,
|
||||
424F11B914643DD5005B8843 /* AttractorKernel.hpp */,
|
||||
4235C47014655A4000C4E90F /* Vectors.hpp */,
|
||||
428EFED4145AFAB4001DBE1B /* Tonemapper.hpp */,
|
||||
42C2D1521461676B001BF28D /* Image.hpp */,
|
||||
42D0F939146E7F6A002B1025 /* ImageFormatBMP.hpp */,
|
||||
42D0F93B146E805D002B1025 /* ImageFormatPNG.hpp */,
|
||||
42D2E1231456175C00FBC16A /* AwesomeAttractorND.1 */,
|
||||
);
|
||||
path = AwesomeAttractorND;
|
||||
|
|
75
AwesomeAttractorND/AttractorKernel.hpp
Normal file
75
AwesomeAttractorND/AttractorKernel.hpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// AttractorKernel.hpp
|
||||
// AwesomeAttractorND
|
||||
//
|
||||
// Created by Joshua Moerman on 11/4/11.
|
||||
// Copyright 2011 Vadovas. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef AwesomeAttractorND_AttractorKernel_hpp
|
||||
#define AwesomeAttractorND_AttractorKernel_hpp
|
||||
|
||||
#include "Vectors.hpp"
|
||||
|
||||
class AttractorKernel {
|
||||
public:
|
||||
virtual void iterate(VectorIterator begin, VectorIterator end, VectorIterator begin2) = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class StaticAttractorKernel : public AttractorKernel, public T {
|
||||
public:
|
||||
virtual void iterate(VectorIterator begin, VectorIterator end, VectorIterator begin2){
|
||||
while (begin != end) {
|
||||
T::calculate(*begin2, *begin);
|
||||
++begin;
|
||||
++begin2;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Unravel {
|
||||
Unravel()
|
||||
: parameters()
|
||||
{
|
||||
parameters[0] = 0.761090;
|
||||
parameters[1] = 1.426758;
|
||||
parameters[2] = 1.516635;
|
||||
parameters[3] = -0.02366;
|
||||
parameters[4] = 2.398894;
|
||||
parameters[5] = -0.32422;
|
||||
parameters[6] = -2.12839;
|
||||
}
|
||||
|
||||
void calculate(VectorConstRef vectorOld, VectorRef vectorNew){
|
||||
vectorNew[0] = parameters[0]*(vectorOld[2] + parameters[1]);
|
||||
vectorNew[1] = parameters[2]*(vectorOld[0] + parameters[3]);
|
||||
vectorNew[2] = parameters[4]*(vectorOld[1] + parameters[5]);
|
||||
|
||||
const double dist = vectorNew[0]*vectorNew[0] + vectorNew[1]*vectorNew[1] + vectorNew[2]*vectorNew[2];
|
||||
|
||||
if(dist > parameters[6]*parameters[6]) {
|
||||
const double sqrtDist = std::sqrt(dist);
|
||||
const double p = 1.0 - parameters[6] * (static_cast<int>(sqrtDist / parameters[6]) + 1.0) / sqrtDist;
|
||||
vectorNew[0] *= p;
|
||||
vectorNew[1] *= p;
|
||||
vectorNew[2] *= p;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
std::array<double, 7> parameters;
|
||||
static const size_t dimension = 3;
|
||||
};
|
||||
|
||||
struct Lorenz {
|
||||
void calculate(VectorConstRef o, VectorRef n);
|
||||
};
|
||||
|
||||
/*
|
||||
IDEA: explicitly instantiate StaticAttractorKernel<Unravel>, StaticAttractorKernel<Lorenz>, ...
|
||||
Thereby we have very little Unravel and Lorenz classes, which do only one thing.
|
||||
And an abstract base-class. And only iterate() is virtual, thus calculate() can be inlined!
|
||||
*/
|
||||
|
||||
#endif
|
|
@ -9,151 +9,7 @@
|
|||
#ifndef AwesomeAttractorND_Image_hpp
|
||||
#define AwesomeAttractorND_Image_hpp
|
||||
|
||||
#include <ostream>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <tr1/memory>
|
||||
|
||||
struct pixel {
|
||||
pixel(double red, double green, double blue)
|
||||
: red(clamp(255*red))
|
||||
, green(clamp(255*green))
|
||||
, blue(clamp(255*blue))
|
||||
{}
|
||||
|
||||
pixel(int red, int green, int blue)
|
||||
: red(clamp(red))
|
||||
, green(clamp(green))
|
||||
, blue(clamp(blue))
|
||||
{}
|
||||
|
||||
void swapRB(){
|
||||
std::swap(red, blue);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t clamp(int n){
|
||||
return std::min(255, std::max(0, n));
|
||||
}
|
||||
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
};
|
||||
|
||||
namespace ImageFormats {
|
||||
namespace bmp {
|
||||
struct bitmap_file_header {
|
||||
uint32_t filesize;
|
||||
uint16_t creator1;
|
||||
uint16_t creator2;
|
||||
uint32_t bmp_offset;
|
||||
|
||||
template <typename DIBT>
|
||||
bitmap_file_header(DIBT dib_header):
|
||||
filesize(dib_header.bytes() + dib_header.header_sz + 12 + 2),
|
||||
creator1(0),
|
||||
creator2(0),
|
||||
bmp_offset(dib_header.header_sz + 12 + 2){}
|
||||
|
||||
void write(std::ostream& out) const {
|
||||
out << "BM";
|
||||
out.write(reinterpret_cast<const char*>(this), 12);
|
||||
}
|
||||
};
|
||||
|
||||
struct bitmapcoreheader {
|
||||
uint32_t header_sz;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint16_t nplanes;
|
||||
uint16_t bitspp;
|
||||
|
||||
bitmapcoreheader(uint16_t width, uint16_t height, uint16_t bitspp = 24):
|
||||
header_sz(sizeof(bitmapcoreheader)),
|
||||
width(width),
|
||||
height(height),
|
||||
nplanes(1),
|
||||
bitspp(bitspp){}
|
||||
|
||||
void write(std::ostream& out) const {
|
||||
out.write(reinterpret_cast<const char*>(this), header_sz);
|
||||
}
|
||||
|
||||
uint32_t bytes(){
|
||||
return width*height*bitspp/8;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P = pixel, typename DIBT = bitmapcoreheader>
|
||||
struct bitmap {
|
||||
typedef P pixel;
|
||||
|
||||
bitmap(uint16_t width, uint16_t height)
|
||||
: dib_header(width, height, sizeof(pixel)*8)
|
||||
, header(dib_header)
|
||||
, data(0) {}
|
||||
|
||||
void write(std::string const & filename){
|
||||
std::ofstream file(filename.c_str());
|
||||
write(file);
|
||||
}
|
||||
|
||||
void write(std::ostream& out){
|
||||
header.write(out);
|
||||
dib_header.write(out);
|
||||
//std::copy_n((char const *)data, dib_header.bytes(), std::ostream_iterator<char>(out));
|
||||
std::copy((char const *)data, (char const *)data + dib_header.bytes(), std::ostream_iterator<char>(out));
|
||||
}
|
||||
|
||||
private:
|
||||
DIBT dib_header;
|
||||
bitmap_file_header header;
|
||||
P const * data;
|
||||
};
|
||||
|
||||
template <typename P = pixel, typename DIBT = bitmapcoreheader>
|
||||
struct bitmap_stream {
|
||||
typedef P pixel;
|
||||
|
||||
bitmap_stream(uint16_t width, uint16_t height, std::string filename)
|
||||
: dib_header(width, height, sizeof(pixel)*8)
|
||||
, header(dib_header)
|
||||
, file(filename.c_str())
|
||||
, x(0)
|
||||
, y(0)
|
||||
{
|
||||
if(!file)
|
||||
throw std::runtime_error("bitmap file could not be opened.");
|
||||
header.write(file);
|
||||
dib_header.write(file);
|
||||
}
|
||||
|
||||
bitmap_stream& operator<<(pixel const & p){
|
||||
if (y >= dib_header.height){
|
||||
throw std::out_of_range("Writing BMP image out of bounds.");
|
||||
}
|
||||
|
||||
pixel p2(p);
|
||||
p2.swapRB();
|
||||
file.write((char const *)&p2, sizeof(pixel));
|
||||
++x;
|
||||
if (x >= dib_header.width){
|
||||
x = 0;
|
||||
++y;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
DIBT dib_header;
|
||||
bitmap_file_header header;
|
||||
std::ofstream file;
|
||||
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
};
|
||||
}
|
||||
}
|
||||
#include "ImageFormatBMP.hpp"
|
||||
#include "ImageFormatPNG.hpp"
|
||||
|
||||
#endif
|
||||
|
|
159
AwesomeAttractorND/ImageFormatBMP.hpp
Normal file
159
AwesomeAttractorND/ImageFormatBMP.hpp
Normal file
|
@ -0,0 +1,159 @@
|
|||
//
|
||||
// ImageFormatBMP.hpp
|
||||
// AwesomeAttractorND
|
||||
//
|
||||
// Created by Joshua Moerman on 11/12/11.
|
||||
// Copyright 2011 Vadovas. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef AwesomeAttractorND_ImageFormatBMP_hpp
|
||||
#define AwesomeAttractorND_ImageFormatBMP_hpp
|
||||
|
||||
#include <ostream>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
namespace ImageFormats {
|
||||
namespace bmp {
|
||||
struct pixelBGR{
|
||||
pixelBGR(double red, double green, double blue)
|
||||
: blue(clamp(255*blue))
|
||||
, green(clamp(255*green))
|
||||
, red(clamp(255*red))
|
||||
{}
|
||||
|
||||
pixelBGR(int red, int green, int blue)
|
||||
: blue(clamp(blue))
|
||||
, green(clamp(green))
|
||||
, red(clamp(red))
|
||||
{}
|
||||
|
||||
void swapRB(){
|
||||
std::swap(red, blue);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t clamp(int n){
|
||||
return std::min(255, std::max(0, n));
|
||||
}
|
||||
|
||||
uint8_t blue;
|
||||
uint8_t green;
|
||||
uint8_t red;
|
||||
};
|
||||
|
||||
struct bitmap_file_header {
|
||||
uint32_t filesize;
|
||||
uint16_t creator1;
|
||||
uint16_t creator2;
|
||||
uint32_t bmp_offset;
|
||||
|
||||
template <typename DIBT>
|
||||
bitmap_file_header(DIBT dib_header):
|
||||
filesize(dib_header.bytes() + dib_header.header_sz + 12 + 2),
|
||||
creator1(0),
|
||||
creator2(0),
|
||||
bmp_offset(dib_header.header_sz + 12 + 2){}
|
||||
|
||||
void write(std::ostream& out) const {
|
||||
out << "BM";
|
||||
out.write(reinterpret_cast<const char*>(this), 12);
|
||||
}
|
||||
};
|
||||
|
||||
struct bitmapcoreheader {
|
||||
uint32_t header_sz;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint16_t nplanes;
|
||||
uint16_t bitspp;
|
||||
|
||||
bitmapcoreheader(uint16_t width, uint16_t height, uint16_t bitspp = 24):
|
||||
header_sz(sizeof(bitmapcoreheader)),
|
||||
width(width),
|
||||
height(height),
|
||||
nplanes(1),
|
||||
bitspp(bitspp){}
|
||||
|
||||
void write(std::ostream& out) const {
|
||||
out.write(reinterpret_cast<const char*>(this), header_sz);
|
||||
}
|
||||
|
||||
uint32_t bytes(){
|
||||
return width*height*bitspp/8;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P = pixelBGR, typename DIBT = bitmapcoreheader>
|
||||
struct bitmap {
|
||||
typedef P pixel;
|
||||
|
||||
bitmap(uint16_t width, uint16_t height)
|
||||
: dib_header(width, height, sizeof(pixel)*8)
|
||||
, header(dib_header)
|
||||
, data(0) {}
|
||||
|
||||
void write(std::string const & filename){
|
||||
std::ofstream file(filename.c_str());
|
||||
write(file);
|
||||
}
|
||||
|
||||
void write(std::ostream& out){
|
||||
header.write(out);
|
||||
dib_header.write(out);
|
||||
//std::copy_n((char const *)data, dib_header.bytes(), std::ostream_iterator<char>(out));
|
||||
std::copy((char const *)data, (char const *)data + dib_header.bytes(), std::ostream_iterator<char>(out));
|
||||
}
|
||||
|
||||
private:
|
||||
DIBT dib_header;
|
||||
bitmap_file_header header;
|
||||
P const * data;
|
||||
};
|
||||
|
||||
template <typename P = pixelBGR, typename DIBT = bitmapcoreheader>
|
||||
struct bitmap_stream {
|
||||
typedef P pixel;
|
||||
|
||||
bitmap_stream(uint16_t width, uint16_t height, std::string filename)
|
||||
: dib_header(width, height, sizeof(pixel)*8)
|
||||
, header(dib_header)
|
||||
, file(filename.c_str())
|
||||
, x(0)
|
||||
, y(0)
|
||||
{
|
||||
if(!file)
|
||||
throw std::runtime_error("bitmap file could not be opened.");
|
||||
header.write(file);
|
||||
dib_header.write(file);
|
||||
}
|
||||
|
||||
bitmap_stream& operator<<(pixel const & p){
|
||||
if (y >= dib_header.height){
|
||||
throw std::out_of_range("Writing BMP image out of bounds.");
|
||||
}
|
||||
|
||||
pixel p2(p);
|
||||
p2.swapRB();
|
||||
file.write((char const *)&p2, sizeof(pixel));
|
||||
++x;
|
||||
if (x >= dib_header.width){
|
||||
x = 0;
|
||||
++y;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
DIBT dib_header;
|
||||
bitmap_file_header header;
|
||||
std::ofstream file;
|
||||
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
107
AwesomeAttractorND/ImageFormatPNG.hpp
Normal file
107
AwesomeAttractorND/ImageFormatPNG.hpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
//
|
||||
// ImageFormatPNG.hpp
|
||||
// AwesomeAttractorND
|
||||
//
|
||||
// Created by Joshua Moerman on 11/12/11.
|
||||
// Copyright 2011 Vadovas. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef AwesomeAttractorND_ImageFormatPNG_hpp
|
||||
#define AwesomeAttractorND_ImageFormatPNG_hpp
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdexcept>
|
||||
#include <png.h>
|
||||
|
||||
namespace ImageFormats {
|
||||
namespace png{
|
||||
struct pixel {
|
||||
pixel()
|
||||
: red(0)
|
||||
, green(0)
|
||||
, blue(0)
|
||||
{}
|
||||
|
||||
pixel(double red, double green, double blue)
|
||||
: red(clamp(255*red))
|
||||
, green(clamp(255*green))
|
||||
, blue(clamp(255*blue))
|
||||
{}
|
||||
|
||||
pixel(int red, int green, int blue)
|
||||
: red(clamp(red))
|
||||
, green(clamp(green))
|
||||
, blue(clamp(blue))
|
||||
{}
|
||||
|
||||
void swapRB(){
|
||||
std::swap(red, blue);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t clamp(int n){
|
||||
return std::min(255, std::max(0, n));
|
||||
}
|
||||
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
};
|
||||
|
||||
struct png_stream{
|
||||
typedef pixel pixel;
|
||||
|
||||
png_stream(uint32_t width, uint32_t height, std::string filename)
|
||||
: fp(0)
|
||||
, png_ptr(0)
|
||||
, info_ptr(0)
|
||||
, row(width)
|
||||
, x(0)
|
||||
{
|
||||
fp = fopen(filename.c_str(), "wb");
|
||||
if(!fp) throw std::runtime_error("Could not open file");
|
||||
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
|
||||
if(!png_ptr) throw std::runtime_error("PNG structure could not be allocated");
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if(!info_ptr) throw std::runtime_error("PNG information structure could not be allocated");
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
png_set_compression_level(png_ptr, 9);
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
}
|
||||
|
||||
~png_stream(){
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
png_destroy_info_struct(png_ptr, &info_ptr);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
png_stream& operator<<(pixel const & p){
|
||||
row[x] = p;
|
||||
++x;
|
||||
if(x >= row.size()){
|
||||
png_write_row(png_ptr, reinterpret_cast<unsigned char const*>(row.data()));
|
||||
x = 0;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
FILE* fp;
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
|
||||
std::vector<pixel> row;
|
||||
uint32_t x;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
133
AwesomeAttractorND/Vectors.hpp
Normal file
133
AwesomeAttractorND/Vectors.hpp
Normal file
|
@ -0,0 +1,133 @@
|
|||
//
|
||||
// Vectors.hpp
|
||||
// AwesomeAttractorND
|
||||
//
|
||||
// Created by Joshua Moerman on 11/5/11.
|
||||
// Copyright 2011 Vadovas. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef AwesomeAttractorND_Vectors_hpp
|
||||
#define AwesomeAttractorND_Vectors_hpp
|
||||
|
||||
#include <iterator>
|
||||
|
||||
typedef double* VectorRef;
|
||||
typedef double const * VectorConstRef;
|
||||
|
||||
struct VectorIterator : public std::iterator<std::random_access_iterator_tag, double> {
|
||||
template <size_t N>
|
||||
static VectorIterator begin(std::array<double, N> & arr, size_t dimension){
|
||||
return VectorIterator(arr.data(), dimension);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
static VectorIterator end(std::array<double, N> & arr, size_t dimension){
|
||||
size_t offset = N - (N % dimension);
|
||||
return VectorIterator(arr.data() + offset, dimension);
|
||||
}
|
||||
|
||||
VectorIterator(VectorIterator const & rh)
|
||||
: data(rh.data)
|
||||
, dimension(rh.dimension)
|
||||
{}
|
||||
|
||||
VectorIterator & operator=(VectorIterator const & rh){
|
||||
data = rh.data;
|
||||
dimension = rh.dimension;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(VectorIterator const & rh) const {
|
||||
return data == rh.data && dimension == rh.dimension;
|
||||
}
|
||||
|
||||
bool operator!=(VectorIterator const & rh) const {
|
||||
return data != rh.data || dimension != rh.dimension;
|
||||
}
|
||||
|
||||
bool operator<(VectorIterator const & rh) const {
|
||||
return data < rh.data;
|
||||
}
|
||||
|
||||
bool operator<=(VectorIterator const & rh) const {
|
||||
return data <= rh.data;
|
||||
}
|
||||
|
||||
bool operator>(VectorIterator const & rh) const {
|
||||
return data > rh.data;
|
||||
}
|
||||
|
||||
bool operator>=(VectorIterator const & rh) const {
|
||||
return data >= rh.data;
|
||||
}
|
||||
|
||||
VectorRef operator*(){
|
||||
return data;
|
||||
}
|
||||
|
||||
VectorRef operator->(){
|
||||
return data;
|
||||
}
|
||||
|
||||
VectorIterator & operator++(){
|
||||
data += dimension;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator operator++(int){
|
||||
VectorIterator temp(*this);
|
||||
++(*this);
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorIterator & operator--(){
|
||||
data -= dimension;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator operator--(int){
|
||||
VectorIterator temp(*this);
|
||||
++(*this);
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorIterator & operator+=(int n){
|
||||
data += n*dimension;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator operator+(int n){
|
||||
VectorIterator temp(*this);
|
||||
temp += n;
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorIterator & operator-=(int n){
|
||||
data -= n*dimension;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator operator-(int n){
|
||||
VectorIterator temp(*this);
|
||||
temp -= n;
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorRef operator[](int n){
|
||||
VectorIterator temp(*this);
|
||||
return *(temp += n);
|
||||
}
|
||||
|
||||
private:
|
||||
VectorIterator(double * data, size_t dimension)
|
||||
: data(data)
|
||||
, dimension(dimension)
|
||||
{}
|
||||
|
||||
VectorIterator();
|
||||
|
||||
double * data;
|
||||
size_t dimension;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -9,10 +9,15 @@
|
|||
#ifndef AwesomeAttractorND_array_hpp
|
||||
#define AwesomeAttractorND_array_hpp
|
||||
|
||||
#include <tr1/array>
|
||||
// workaround to easily work in xcode :D
|
||||
|
||||
#ifndef __APPLE__
|
||||
#include <array>
|
||||
#else
|
||||
#include <tr1/array>
|
||||
namespace std {
|
||||
using tr1::array;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,33 +7,49 @@
|
|||
//
|
||||
|
||||
#include <iostream>
|
||||
#include "array.hpp"
|
||||
|
||||
#include "Logging.hpp"
|
||||
|
||||
#include "Canvas.hpp"
|
||||
#include "Tonemapper.hpp"
|
||||
#include "Image.hpp"
|
||||
#include "Vectors.hpp"
|
||||
#include "AttractorKernel.hpp"
|
||||
|
||||
typedef Canvas2D Canvas;
|
||||
|
||||
void fill(Canvas & canvas);
|
||||
double unit_random(){
|
||||
return rand()/ (double) RAND_MAX * 2.0 - 1.0;
|
||||
}
|
||||
|
||||
void fill(Canvas & canvas){
|
||||
const unsigned int it = 100000000;
|
||||
std::array<double, 10000> vectors;
|
||||
std::array<double, 10000> old_vectors;
|
||||
|
||||
std::generate(vectors.begin(), vectors.end(), unit_random);
|
||||
std::generate(old_vectors.begin(), old_vectors.end(), unit_random);
|
||||
|
||||
StaticAttractorKernel<Unravel> magic;
|
||||
|
||||
const unsigned int it = 100000;
|
||||
|
||||
for (unsigned int i = 0; i < it; ++i){
|
||||
double x = 2.0 * (rand() / (double) RAND_MAX - 0.5);
|
||||
double y = 2.0 * (rand() / (double) RAND_MAX - 0.5);
|
||||
double position[2] = {x*x*2.0 - 1.0, y};
|
||||
canvas.plot(position);
|
||||
std::array<double, 10000> & v = (i%2 == 1) ? vectors : old_vectors;
|
||||
std::array<double, 10000> & vo = (i%2 == 0) ? vectors : old_vectors;
|
||||
|
||||
magic.iterate(VectorIterator::begin(v, 3), VectorIterator::end(v, 3), VectorIterator::begin(vo, 3));
|
||||
|
||||
for(VectorIterator it = VectorIterator::begin(v, 3); it != VectorIterator::end(v, 3); ++it)
|
||||
canvas.plot(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void output(Canvas const & canvas);
|
||||
void output(Canvas const & canvas){
|
||||
Tonemappers::GammaCorrector tonemapper;
|
||||
tonemapper.analyse(canvas);
|
||||
|
||||
ImageFormats::bmp::bitmap_stream<> image(canvas.size<0>(), canvas.size<1>(), "test.bmp");
|
||||
ImageFormats::png::png_stream image(canvas.size<0>(), canvas.size<1>(), "test.png");
|
||||
tonemapper.process(canvas, image);
|
||||
}
|
||||
|
||||
|
@ -42,7 +58,7 @@ int main (int, const char * []){
|
|||
l.start("all");
|
||||
|
||||
l.log("creating canvas");
|
||||
Canvas canvas(2048, 2048);
|
||||
Canvas canvas(8000, 8000);
|
||||
l.log("filling canvas");
|
||||
fill(canvas);
|
||||
l.log("outputting canvas");
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
//
|
||||
// nd_array.hpp
|
||||
// AwesomeAttractorND
|
||||
//
|
||||
// Created by Joshua Moerman on 10/25/11.
|
||||
// Copyright 2011 Vadovas. All rights reserved.
|
||||
//
|
||||
|
||||
/*
|
||||
Dynamic multi-dimensional array.
|
||||
With the usual c-syntax: v[x][y][z].
|
||||
Memory is allocated as one big block, instead of multiple smaller blocks (which is the case with std::vector<std::vector<...>>).
|
||||
Showed no difference in speed compared to std::array<std::array<...>> (in release build).
|
||||
|
||||
it is not yet standard compliant.
|
||||
*/
|
||||
|
||||
#ifndef AwesomeAttractorND_nd_array_hpp
|
||||
#define AwesomeAttractorND_nd_array_hpp
|
||||
|
||||
#include <stdexcept>
|
||||
#include <numeric>
|
||||
#include <iterator>
|
||||
#include "array.hpp"
|
||||
|
||||
template <typename T, size_t dimension>
|
||||
class nd_array{
|
||||
public:
|
||||
typedef T & reference;
|
||||
typedef T const & const_reference;
|
||||
typedef T * iterator;
|
||||
typedef T const * const_iterator;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef T const * const_pointer;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
template <size_type N>
|
||||
struct proxy {
|
||||
nd_array * const data;
|
||||
size_t const offset;
|
||||
|
||||
proxy(nd_array * const c, size_t o)
|
||||
: data(c)
|
||||
, offset(o)
|
||||
{}
|
||||
|
||||
proxy<N-1> operator[](size_t y){
|
||||
if (N == 0) throw std::logic_error("called operator[] on a value");
|
||||
return proxy<N-1>(data, data->sizes[dimension - N]*offset + y);
|
||||
}
|
||||
|
||||
operator reference(){
|
||||
if (N != 0) throw std::logic_error("using a non-value");
|
||||
return *(data->data + offset);
|
||||
}
|
||||
|
||||
reference operator=(T const & n){
|
||||
if (N != 0) throw std::logic_error("assignment to a non-value");
|
||||
return *(data->data + offset) = n;
|
||||
}
|
||||
};
|
||||
|
||||
template <size_type N>
|
||||
struct const_proxy {
|
||||
nd_array const * const data;
|
||||
size_t const offset;
|
||||
|
||||
const_proxy(nd_array const * const c, size_t o)
|
||||
: data(c)
|
||||
, offset(o)
|
||||
{}
|
||||
|
||||
const_proxy<N-1> operator[](size_t y) const {
|
||||
if (N == 0) throw std::logic_error("called operator[] on a value");
|
||||
return const_proxy<N-1>(data, data->sizes[dimension - N]*offset + y);
|
||||
}
|
||||
|
||||
operator const_reference() const {
|
||||
if (N != 0) throw std::logic_error("using a non-value");
|
||||
return *(data->data + offset);
|
||||
}
|
||||
};
|
||||
|
||||
nd_array(size_type width, size_type height)
|
||||
: data(0)
|
||||
, sizes()
|
||||
{
|
||||
if (dimension != 2) throw std::logic_error("wrong constructor");
|
||||
sizes[0] = width;
|
||||
sizes[1] = height;
|
||||
data = new T[width*height];
|
||||
}
|
||||
|
||||
nd_array(size_type width, size_type height, size_type depth)
|
||||
: data(0)
|
||||
, sizes()
|
||||
{
|
||||
if (dimension != 3) throw std::logic_error("wrong constructor");
|
||||
sizes[0] = width;
|
||||
sizes[1] = height;
|
||||
sizes[2] = depth;
|
||||
data = new T[width*height*depth];
|
||||
}
|
||||
|
||||
~nd_array(){
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
size_type get_size(size_type d) const {
|
||||
return sizes[d];
|
||||
}
|
||||
|
||||
size_type size() const {
|
||||
return std::accumulate(sizes.begin(), sizes.end(), 1, std::multiplies<size_type>());
|
||||
}
|
||||
|
||||
proxy<dimension-1> operator[](size_t x){
|
||||
return proxy<dimension-1>(this, x);
|
||||
}
|
||||
|
||||
const_proxy<dimension-1> operator[](size_t x) const {
|
||||
return const_proxy<dimension-1>(this, x);
|
||||
}
|
||||
|
||||
iterator begin(){
|
||||
return data;
|
||||
}
|
||||
|
||||
iterator end(){
|
||||
size_type length = size();
|
||||
return data + length;
|
||||
}
|
||||
|
||||
const_iterator cbegin() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
const_iterator cend() const {
|
||||
size_type length = size();
|
||||
return data + length;
|
||||
}
|
||||
|
||||
private:
|
||||
T * data;
|
||||
std::array<size_type, dimension> sizes;
|
||||
};
|
||||
|
||||
#endif
|
Reference in a new issue