// // 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() 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 #include #include "array.hpp" class Canvas2D { typedef unsigned int value_type; typedef std::vector Row; typedef std::vector Storage; public: Canvas2D(size_t width, size_t height) : storage(height, Row(width, 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 c = 0.5*position[0]*width + width*.5; const size_t r = 0.5*position[1]*width + height*.5; if(c < width && r < height) { storage[r][c]++; } } size_t size() const { return size<0>() * size<1>(); } template size_t size() const { if ( N == 0 ) return storage.front().size(); if ( N == 1 ) return storage.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 { iterator(iterator const & rh) : canvas(rh.canvas) , c(rh.c) , r(rh.r) {} iterator & operator++(){ ++c; if (c >= canvas->size<0>()) { c = 0; ++r; } return *this; } iterator operator++(int){ iterator temp(*this); ++(*this); return temp; } bool operator==(iterator const & rh) const { return canvas == rh.canvas && c == rh.c && r == rh.r; } bool operator!=(iterator const & rh) const { return canvas != rh.canvas || c != rh.c || r != rh.r; } value_type & operator*(){ return (*canvas)[r][c]; } value_type & operator->(){ return (*canvas)[r][c]; } private: friend class Canvas2D; iterator(Canvas2D * canvas, size_t c = 0, size_t r = 0) : canvas(canvas) , c(c) , r(r) {} iterator(); Canvas2D * canvas; size_t c; size_t r; }; struct const_iterator : public std::iterator { const_iterator(const_iterator const & rh) : canvas(rh.canvas) , c(rh.c) , r(rh.r) {} const_iterator & operator++(){ ++c; if (c >= canvas->size<0>()) { c = 0; ++r; } return *this; } const_iterator operator++(int){ const_iterator temp(*this); ++(*this); return temp; } bool operator==(const_iterator const & rh) const { return canvas == rh.canvas && c == rh.c && r == rh.r; } bool operator!=(const_iterator const & rh) const { return canvas != rh.canvas || c != rh.c || r != rh.r; } value_type const & operator*() const { return (*canvas)[r][c]; } value_type const & operator->() const { return (*canvas)[r][c]; } private: friend class Canvas2D; const_iterator(Canvas2D const * canvas, size_t c = 0, size_t r = 0) : canvas(canvas) , c(c) , r(r) {} const_iterator(); Canvas2D const * canvas; size_t c; size_t r; }; private: Storage storage; }; #endif