|
|
|
//
|
|
|
|
// Canvas.hpp
|
|
|
|
// AwesomeAttractorND
|
|
|
|
//
|
|
|
|
// Created by Joshua Moerman on 10/28/11.
|
|
|
|
// Copyright 2011 Vadovas. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
/*
|
|
|
|
Interface (or Concept) Canvas:
|
|
|
|
Canvas canvas(width, height, ...); Constructs a Canvas with given dimensions
|
|
|
|
canvas[x][y]...[z] Returns a (const) reference to an element
|
|
|
|
canvas.plot(position) Plots on the canvas (where position is normalized, ie in the unit-cube)
|
|
|
|
canvas.size<N>() gives width/size for the given dimension N.
|
|
|
|
canvas.begin() .end() gives iterators to the elements (directly)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef AwesomeAttractorND_Canvas_hpp
|
|
|
|
#define AwesomeAttractorND_Canvas_hpp
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
#include <iterator>
|
|
|
|
#include "array.hpp"
|
|
|
|
|
|
|
|
class Canvas2D {
|
|
|
|
typedef unsigned int value_type;
|
|
|
|
typedef std::vector<value_type> Row;
|
|
|
|
typedef std::vector<Row> Storage;
|
|
|
|
|
|
|
|
public:
|
|
|
|
Canvas2D(size_t width, size_t height)
|
|
|
|
: storage(width, Storage::value_type(height, 0))
|
|
|
|
{}
|
|
|
|
|
|
|
|
Row & operator[](size_t r){
|
|
|
|
return storage[r];
|
|
|
|
}
|
|
|
|
|
|
|
|
Row const & operator[](size_t r) const {
|
|
|
|
return storage[r];
|
|
|
|
}
|
|
|
|
|
|
|
|
void plot(double const * const position){
|
|
|
|
const size_t width = size<0>();
|
|
|
|
const size_t height = size<1>();
|
|
|
|
|
|
|
|
const size_t x = 0.5*position[0]*width + width*.5;
|
|
|
|
const size_t y = 0.5*position[1]*width + height*.5;
|
|
|
|
|
|
|
|
if(x < width && y < height) {
|
|
|
|
storage[x][y]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <size_t N>
|
|
|
|
size_t size() const {
|
|
|
|
if ( N == 0 ) return storage.size();
|
|
|
|
if ( N == 1 ) return storage.front().size();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct iterator;
|
|
|
|
iterator begin(){
|
|
|
|
return iterator(this);
|
|
|
|
}
|
|
|
|
iterator end(){
|
|
|
|
return iterator(this, 0, size<1>());
|
|
|
|
};
|
|
|
|
|
|
|
|
struct const_iterator;
|
|
|
|
const_iterator begin() const {
|
|
|
|
return const_iterator(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
const_iterator end() const {
|
|
|
|
return const_iterator(this, 0, size<1>());
|
|
|
|
}
|
|
|
|
|
|
|
|
const_iterator cbegin() const {
|
|
|
|
return const_iterator(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
const_iterator cend() const {
|
|
|
|
return const_iterator(this, 0, size<1>());
|
|
|
|
}
|
|
|
|
|
|
|
|
struct iterator : public std::iterator<std::forward_iterator_tag, value_type> {
|
|
|
|
iterator(iterator const & rh)
|
|
|
|
: canvas(rh.canvas)
|
|
|
|
, x(rh.x)
|
|
|
|
, y(rh.y)
|
|
|
|
{}
|
|
|
|
|
|
|
|
iterator & operator++(){
|
|
|
|
++x;
|
|
|
|
if (x >= canvas->size<0>()) {
|
|
|
|
x = 0;
|
|
|
|
++y;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
iterator operator++(int){
|
|
|
|
iterator temp(*this);
|
|
|
|
++(*this);
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(iterator const & rh) const {
|
|
|
|
return canvas == rh.canvas && x == rh.x && y == rh.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(iterator const & rh) const {
|
|
|
|
return canvas != rh.canvas || x != rh.x || y != rh.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
value_type & operator*(){
|
|
|
|
return (*canvas)[x][y];
|
|
|
|
}
|
|
|
|
|
|
|
|
value_type & operator->(){
|
|
|
|
return (*canvas)[x][y];
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
friend class Canvas2D;
|
|
|
|
iterator(Canvas2D * canvas, size_t x = 0, size_t y = 0)
|
|
|
|
: canvas(canvas)
|
|
|
|
, x(x)
|
|
|
|
, y(y)
|
|
|
|
{}
|
|
|
|
|
|
|
|
iterator();
|
|
|
|
|
|
|
|
Canvas2D * canvas;
|
|
|
|
size_t x;
|
|
|
|
size_t y;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct const_iterator : public std::iterator<std::forward_iterator_tag, value_type const> {
|
|
|
|
const_iterator(const_iterator const & rh)
|
|
|
|
: canvas(rh.canvas)
|
|
|
|
, x(rh.x)
|
|
|
|
, y(rh.y)
|
|
|
|
{}
|
|
|
|
|
|
|
|
const_iterator & operator++(){
|
|
|
|
++x;
|
|
|
|
if (x >= canvas->size<0>()) {
|
|
|
|
x = 0;
|
|
|
|
++y;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
const_iterator operator++(int){
|
|
|
|
const_iterator temp(*this);
|
|
|
|
++(*this);
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const_iterator const & rh) const {
|
|
|
|
return canvas == rh.canvas && x == rh.x && y == rh.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const_iterator const & rh) const {
|
|
|
|
return canvas != rh.canvas || x != rh.x || y != rh.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
value_type const & operator*() const {
|
|
|
|
return (*canvas)[x][y];
|
|
|
|
}
|
|
|
|
|
|
|
|
value_type const & operator->() const {
|
|
|
|
return (*canvas)[x][y];
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
friend class Canvas2D;
|
|
|
|
const_iterator(Canvas2D const * canvas, size_t x = 0, size_t y = 0)
|
|
|
|
: canvas(canvas)
|
|
|
|
, x(x)
|
|
|
|
, y(y)
|
|
|
|
{}
|
|
|
|
|
|
|
|
const_iterator();
|
|
|
|
|
|
|
|
Canvas2D const * canvas;
|
|
|
|
size_t x;
|
|
|
|
size_t y;
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
Storage storage;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|