|
@ -21,6 +21,7 @@ |
|
|
#include <vector> |
|
|
#include <vector> |
|
|
#include <iterator> |
|
|
#include <iterator> |
|
|
#include <array> |
|
|
#include <array> |
|
|
|
|
|
#include <numeric> |
|
|
|
|
|
|
|
|
template <typename T> |
|
|
template <typename T> |
|
|
class Canvas2D { |
|
|
class Canvas2D { |
|
@ -30,6 +31,7 @@ class Canvas2D { |
|
|
|
|
|
|
|
|
public: |
|
|
public: |
|
|
static constexpr size_t dimension = 2; |
|
|
static constexpr size_t dimension = 2; |
|
|
|
|
|
static constexpr bool layered = false; |
|
|
|
|
|
|
|
|
Canvas2D(size_t width, size_t height) |
|
|
Canvas2D(size_t width, size_t height) |
|
|
: storage(height, Row(width, 0)) |
|
|
: storage(height, Row(width, 0)) |
|
@ -47,13 +49,12 @@ public: |
|
|
const size_t width = size<0>(); |
|
|
const size_t width = size<0>(); |
|
|
const size_t height = size<1>(); |
|
|
const size_t height = size<1>(); |
|
|
|
|
|
|
|
|
const size_t c = 0.5*position[0]*width + width*.5; |
|
|
const int c = 0.5*position[0]*width + width*.5; |
|
|
const size_t r = 0.5*position[1]*width + height*.5; |
|
|
const int r = 0.5*position[1]*width + height*.5; |
|
|
|
|
|
|
|
|
if(c < width && r < height) { |
|
|
if(0 <= c && c < width && 0 <= r && r < height) |
|
|
storage[r][c]++; |
|
|
storage[r][c]++; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
size_t size() const { |
|
|
size_t size() const { |
|
|
return size<0>() * size<1>(); |
|
|
return size<0>() * size<1>(); |
|
@ -213,6 +214,7 @@ template <typename Canvas> |
|
|
class LayeredCanvas { |
|
|
class LayeredCanvas { |
|
|
public: |
|
|
public: |
|
|
static constexpr size_t dimension = Canvas::dimension; |
|
|
static constexpr size_t dimension = Canvas::dimension; |
|
|
|
|
|
static constexpr bool layered = true; |
|
|
|
|
|
|
|
|
LayeredCanvas(size_t width, size_t height, size_t layers) |
|
|
LayeredCanvas(size_t width, size_t height, size_t layers) |
|
|
: canvae(layers, Canvas(width, height)) |
|
|
: canvae(layers, Canvas(width, height)) |
|
@ -230,6 +232,10 @@ public: |
|
|
return canvae.size(); |
|
|
return canvae.size(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
size_t size() const { |
|
|
|
|
|
return canvae.front().size(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
template <size_t N> |
|
|
template <size_t N> |
|
|
size_t size() const { |
|
|
size_t size() const { |
|
|
return canvae.front().size<N>(); |
|
|
return canvae.front().size<N>(); |
|
@ -243,4 +249,26 @@ private: |
|
|
std::vector<Canvas> canvae; |
|
|
std::vector<Canvas> canvae; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
template <typename C> |
|
|
|
|
|
typename std::enable_if<!C::layered, bool>::type filled(C const & canvas, double threshold) { |
|
|
|
|
|
struct functor { |
|
|
|
|
|
size_t operator()(size_t x, size_t y){ |
|
|
|
|
|
if(y > 0) return ++x; |
|
|
|
|
|
else return x; |
|
|
|
|
|
} |
|
|
|
|
|
} f; |
|
|
|
|
|
size_t nonempty_pixels = std::accumulate(canvas.begin(), canvas.end(), 0ul, f); |
|
|
|
|
|
return nonempty_pixels > threshold * canvas.size(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename C> |
|
|
|
|
|
typename std::enable_if<C::layered, bool>::type filled(C const & canvas, double threshold) { |
|
|
|
|
|
for (unsigned int l = 0; l < canvas.layers(); ++l) { |
|
|
|
|
|
if (!filled(canvas[l], threshold)) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
#endif |
|
|
#endif |
|
|