made a nd_array, and stub for new AA framework
This commit is contained in:
parent
8241890a4e
commit
7b1e7fd7e3
6 changed files with 472 additions and 4 deletions
|
@ -25,9 +25,13 @@
|
|||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
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>"; };
|
||||
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 */
|
||||
|
@ -61,6 +65,10 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
42D2E1211456175C00FBC16A /* main.cpp */,
|
||||
42D2E12A1456176800FBC16A /* nd_array.hpp */,
|
||||
428EFECF145AF6E0001DBE1B /* Canvas.hpp */,
|
||||
428EFED4145AFAB4001DBE1B /* Tonemapper.hpp */,
|
||||
42C2D1521461676B001BF28D /* Image.hpp */,
|
||||
42D2E1231456175C00FBC16A /* AwesomeAttractorND.1 */,
|
||||
);
|
||||
path = AwesomeAttractorND;
|
||||
|
@ -171,6 +179,7 @@
|
|||
42D2E1281456175C00FBC16A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
|
@ -178,6 +187,7 @@
|
|||
42D2E1291456175C00FBC16A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
|
@ -201,6 +211,7 @@
|
|||
42D2E1291456175C00FBC16A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
|
|
37
AwesomeAttractorND/Canvas.hpp
Normal file
37
AwesomeAttractorND/Canvas.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// Canvas.hpp
|
||||
// AwesomeAttractorND
|
||||
//
|
||||
// Created by Joshua Moerman on 10/28/11.
|
||||
// Copyright 2011 Vadovas. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef AwesomeAttractorND_Canvas_hpp
|
||||
#define AwesomeAttractorND_Canvas_hpp
|
||||
|
||||
#include "nd_array.hpp"
|
||||
|
||||
class Canvas2D : public nd_array<unsigned int, 2>{
|
||||
typedef Canvas2D self;
|
||||
typedef nd_array<unsigned int, 2> super;
|
||||
|
||||
public:
|
||||
Canvas2D(size_t width, size_t height)
|
||||
: super(width, height)
|
||||
{}
|
||||
|
||||
void plot(double const * const position){
|
||||
const size_t width = get_size(0);
|
||||
const size_t height = get_size(1);
|
||||
|
||||
const size_t x = position[0]*width + width*.5;
|
||||
const size_t y = position[1]*width + height*.5;
|
||||
|
||||
if(x < width && y < height) {
|
||||
(*this)[x][y]++;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
147
AwesomeAttractorND/Image.hpp
Normal file
147
AwesomeAttractorND/Image.hpp
Normal file
|
@ -0,0 +1,147 @@
|
|||
//
|
||||
// Image.hpp
|
||||
// AwesomeAttractorND
|
||||
//
|
||||
// Created by Joshua Moerman on 11/2/11.
|
||||
// Copyright 2011 Vadovas. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef AwesomeAttractorND_Image_hpp
|
||||
#define AwesomeAttractorND_Image_hpp
|
||||
|
||||
#include <ostream>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <tr1/memory>
|
||||
|
||||
struct pixel {
|
||||
friend class Image;
|
||||
|
||||
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))
|
||||
{}
|
||||
|
||||
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(int width, int height, int 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);
|
||||
}
|
||||
|
||||
unsigned int bytes(){
|
||||
return width*height*bitspp/8;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P = pixel, typename DIBT = bitmapcoreheader>
|
||||
struct bitmap {
|
||||
bitmap(int width, int height)
|
||||
: dib_header(width, height, sizeof(P)*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 DIBT = bitmapcoreheader>
|
||||
struct bitmap_stream {
|
||||
typedef pixel pixel;
|
||||
|
||||
bitmap_stream(int width, int height, std::string filename)
|
||||
: dib_header(width, height)
|
||||
, header(dib_header)
|
||||
, file(filename.c_str())
|
||||
{
|
||||
header.write(file);
|
||||
dib_header.write(file);
|
||||
}
|
||||
|
||||
bitmap_stream& operator<<(pixel const & p){
|
||||
file.write(&p, 3);
|
||||
++x;
|
||||
if (x >= dib_header.width){
|
||||
x = 0;
|
||||
++y;
|
||||
}
|
||||
if (y >= dib_header.height){
|
||||
throw std::out_of_range("Writing BMP image out of bounds.");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
DIBT dib_header;
|
||||
bitmap_file_header header;
|
||||
std::ofstream file;
|
||||
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
37
AwesomeAttractorND/Tonemapper.hpp
Normal file
37
AwesomeAttractorND/Tonemapper.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// Tonemapper.hpp
|
||||
// AwesomeAttractorND
|
||||
//
|
||||
// Created by Joshua Moerman on 10/28/11.
|
||||
// Copyright 2011 Vadovas. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef AwesomeAttractorND_Tonemapper_hpp
|
||||
#define AwesomeAttractorND_Tonemapper_hpp
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Tonemappers {
|
||||
|
||||
class Normalizer2D {
|
||||
unsigned int max;
|
||||
|
||||
template <typename C>
|
||||
void analyse(C const & canvas){
|
||||
max = *std::max_element(canvas.cbegin(), canvas.cend());
|
||||
}
|
||||
|
||||
template <typename C, typename I>
|
||||
void process(C const & canvas, I & image){
|
||||
for (size_t x = 0; x < canvas.get_size(0); ++x) {
|
||||
for (size_t y = 0; y < canvas.get_size(1); ++y) {
|
||||
const double grayscale = (double) canvas[x][y] / (double) max;
|
||||
image << I::pixel(grayscale, grayscale, grayscale);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -8,11 +8,95 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
int main (int argc, const char * argv[])
|
||||
{
|
||||
#include "nd_array.hpp"
|
||||
#include "Canvas.hpp"
|
||||
#include "Tonemapper.hpp"
|
||||
#include "Image.hpp"
|
||||
|
||||
// insert code here...
|
||||
std::cout << "Hello, World!\n";
|
||||
const size_t width = 512;
|
||||
const size_t height = 64;
|
||||
const size_t depth = 32;
|
||||
|
||||
typedef nd_array<double, 3> array;
|
||||
|
||||
double calculate1(array & c){
|
||||
double mean = 0.0;
|
||||
for (unsigned int x = 0; x < width; ++x) {
|
||||
for (unsigned int y = 0; y < height; ++y) {
|
||||
for (unsigned int z = 0; z < depth; ++z) {
|
||||
mean += 1.0/(width*height*depth) * c[x][y][z];
|
||||
}
|
||||
}
|
||||
}
|
||||
return mean;
|
||||
}
|
||||
|
||||
void calculate2(array & c, double mean){
|
||||
for (unsigned int x = 0; x < width; ++x) {
|
||||
for (unsigned int y = 0; y < height; ++y) {
|
||||
for (unsigned int z = 0; z < depth; ++z) {
|
||||
c[x][y][z] = c[x/3][y][z/2] * mean / 200.0 + mean - x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void calculate(array & c){
|
||||
std::cout << "Calculating..." << std::endl;
|
||||
|
||||
for (unsigned int i = 0; i < 1000; ++i) {
|
||||
double mean = calculate1(c);
|
||||
calculate2(c, mean);
|
||||
}
|
||||
}
|
||||
|
||||
void fill(array & c){
|
||||
std::cout << "Filling..." << std::endl;
|
||||
|
||||
for (unsigned int x = 0; x < width; ++x) {
|
||||
for (unsigned int y = 0; y < height; ++y) {
|
||||
for (unsigned int z = 0; z < depth; ++z) {
|
||||
c[x][y][z] = x + z;
|
||||
if (y == 5) {
|
||||
c[x][y][z] = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void output(array & c){
|
||||
std::cout << "Outputting..." << std::endl;
|
||||
|
||||
for (unsigned int y = 0; y < 10; ++y) {
|
||||
for (unsigned int x = 0; x < 10; ++x) {
|
||||
std::cout << c[x][y][2] << '\t';
|
||||
}
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
std::cout << "Outputting addresses..." << std::endl;
|
||||
|
||||
for (unsigned int z = 20; z < 30; ++z) {
|
||||
double & n = c[32][64][z];
|
||||
std::cout << &n << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, const char * argv[]){
|
||||
|
||||
std::cout << "Creating..." << std::endl;
|
||||
|
||||
array c(width, height, depth);
|
||||
|
||||
fill(c);
|
||||
|
||||
calculate(c);
|
||||
|
||||
output(c);
|
||||
|
||||
std::cout << "Done" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
152
AwesomeAttractorND/nd_array.hpp
Normal file
152
AwesomeAttractorND/nd_array.hpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
//
|
||||
// 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 <tr1/array>
|
||||
|
||||
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 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(), 0, 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 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::tr1::array<size_type, dimension> sizes;
|
||||
};
|
||||
|
||||
#endif
|
Reference in a new issue