Add generator & pixmap mapping functions
This commit is contained in:
parent
395df40793
commit
da7b71b504
1 changed files with 120 additions and 0 deletions
120
libs/pcg/include/psemek/pcg/map.hpp
Normal file
120
libs/pcg/include/psemek/pcg/map.hpp
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <psemek/gfx/pixmap.hpp>
|
||||||
|
#include <psemek/pcg/seamless.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace psemek::pcg
|
||||||
|
{
|
||||||
|
|
||||||
|
// TODO: return a proper generator instead of a lambda
|
||||||
|
template <typename Gen, typename F>
|
||||||
|
auto map_(Gen && gen, F && f)
|
||||||
|
{
|
||||||
|
return [gen = std::forward<Gen>(gen), f = std::forward<F>(f)](float x, float y)
|
||||||
|
{
|
||||||
|
return f(gen(x, y));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename F, typename R = decltype(std::declval<F>()(std::declval<T>())),
|
||||||
|
typename = std::enable_if_t<std::is_same_v<T, R>>>
|
||||||
|
auto map(gfx::basic_pixmap<T> 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 <typename T, typename F, typename R = decltype(std::declval<F>()(std::declval<T>())),
|
||||||
|
typename = std::enable_if_t<!std::is_same_v<T, R>>>
|
||||||
|
auto map(gfx::basic_pixmap<T> const & p, F && f)
|
||||||
|
{
|
||||||
|
gfx::basic_pixmap<R> 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 <typename T, typename F>
|
||||||
|
auto map_neumann(gfx::basic_pixmap<T> const & pixmap, F && f, seamless_tag)
|
||||||
|
{
|
||||||
|
std::vector<T> 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<R> 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 <typename T, typename F>
|
||||||
|
auto map_moore(gfx::basic_pixmap<T> const & pixmap, F && f, seamless_tag)
|
||||||
|
{
|
||||||
|
std::vector<T> 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<R> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue