From da7b71b5040adf8a57903df84fe3ad9ccad4c477 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sun, 13 Sep 2020 11:05:24 +0300 Subject: [PATCH] Add generator & pixmap mapping functions --- libs/pcg/include/psemek/pcg/map.hpp | 120 ++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 libs/pcg/include/psemek/pcg/map.hpp diff --git a/libs/pcg/include/psemek/pcg/map.hpp b/libs/pcg/include/psemek/pcg/map.hpp new file mode 100644 index 00000000..e0735799 --- /dev/null +++ b/libs/pcg/include/psemek/pcg/map.hpp @@ -0,0 +1,120 @@ +#pragma once + +#include +#include + +#include +#include + +namespace psemek::pcg +{ + + // TODO: return a proper generator instead of a lambda + template + auto map_(Gen && gen, F && f) + { + return [gen = std::forward(gen), f = std::forward(f)](float x, float y) + { + return f(gen(x, y)); + }; + } + + template ()(std::declval())), + typename = std::enable_if_t>> + auto map(gfx::basic_pixmap p, F && f) + { + for (std::size_t j = 0; j < p.height(); ++j) + { + for (std::size_t i = 0; i < p.width(); ++i) + { + p(i, j) = f(p(i, j)); + } + } + + return p; + } + + template ()(std::declval())), + typename = std::enable_if_t>> + auto map(gfx::basic_pixmap const & p, F && f) + { + gfx::basic_pixmap result({p.width(), p.height()}); + + for (std::size_t j = 0; j < p.height(); ++j) + { + for (std::size_t i = 0; i < p.width(); ++i) + { + result(i, j) = f(p(i, j)); + } + } + + return result; + } + + template + auto map_neumann(gfx::basic_pixmap const & pixmap, F && f, seamless_tag) + { + std::vector n; + n.reserve(4); + + using R = decltype(f(pixmap(0, 0), n)); + + std::size_t const w = pixmap.width(); + std::size_t const h = pixmap.height(); + + gfx::basic_pixmap result({w, h}); + + for (std::size_t j = 0; j < h; ++j) + { + for (std::size_t i = 0; i < w; ++i) + { + n.push_back(pixmap((i + 1) % w, j)); + n.push_back(pixmap((i + w - 1) % w, j)); + n.push_back(pixmap(i, (j + 1) % h)); + n.push_back(pixmap(i, (j + h - 1) % h)); + + result(i, j) = f(pixmap(i, j), n); + + n.clear(); + } + } + + return result; + } + + template + auto map_moore(gfx::basic_pixmap const & pixmap, F && f, seamless_tag) + { + std::vector n; + n.reserve(8); + + using R = decltype(f(pixmap(0, 0), n)); + + std::size_t const w = pixmap.width(); + std::size_t const h = pixmap.height(); + + gfx::basic_pixmap result({w, h}); + + for (std::size_t j = 0; j < h; ++j) + { + for (std::size_t i = 0; i < w; ++i) + { + n.push_back(pixmap((i + 1) % w, j)); + n.push_back(pixmap((i + 1) % w, (j + 1) % h)); + n.push_back(pixmap(i, (j + 1) % h)); + n.push_back(pixmap((i + w - 1) % w, (j + 1) % h)); + n.push_back(pixmap((i + w - 1) % w, j)); + n.push_back(pixmap((i + w - 1) % w, (j + h - 1) % h)); + n.push_back(pixmap(i, (j + h - 1) % h)); + n.push_back(pixmap((i + 1) % w, (j + h - 1) % h)); + + result(i, j) = f(pixmap(i, j), n); + + n.clear(); + } + } + + return result; + } + +}