46 lines
979 B
C++
46 lines
979 B
C++
#include <psemek/vecr/path.hpp>
|
|
#include <psemek/geom/interval.hpp>
|
|
#include <psemek/geom/math.hpp>
|
|
|
|
namespace psemek::vecr
|
|
{
|
|
|
|
path closed(path path)
|
|
{
|
|
path.points.push_back(path.points.front());
|
|
return path;
|
|
}
|
|
|
|
sdf_sample sdf(path const & s, geom::point<float, 2> const & p, bool closed)
|
|
{
|
|
sdf_sample result;
|
|
for (std::size_t i = 0; i + (closed ? 0 : 1) < s.points.size(); ++i)
|
|
{
|
|
auto const j = (i + 1) % s.points.size();
|
|
auto const e = s.points[j] - s.points[i];
|
|
auto const v = p - s.points[i];
|
|
auto const t = geom::clamp(geom::dot(v, e) / geom::dot(e, e), {0.f, 1.f});
|
|
auto const q = v - t * e;
|
|
auto const l = geom::length(q);
|
|
if (geom::make_min(result.value, l))
|
|
{
|
|
if (l > 0.f)
|
|
result.gradient = q / l;
|
|
else
|
|
result.gradient = {0.f, 0.f};
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
geom::box<float, 2> bbox(path const & s)
|
|
{
|
|
geom::box<float, 2> result;
|
|
|
|
for (auto const & p : s.points)
|
|
result |= p;
|
|
|
|
return result;
|
|
}
|
|
|
|
}
|