Add geom::polygon_distance
This commit is contained in:
parent
d01a8186d8
commit
3f382651c4
1 changed files with 68 additions and 0 deletions
|
|
@ -6,6 +6,7 @@
|
|||
#include <psemek/geom/simplex.hpp>
|
||||
#include <psemek/geom/gauss.hpp>
|
||||
#include <psemek/geom/contains.hpp>
|
||||
#include <psemek/util/range.hpp>
|
||||
|
||||
namespace psemek::geom
|
||||
{
|
||||
|
|
@ -93,4 +94,71 @@ namespace psemek::geom
|
|||
return std::min(distance(p, simplex{s[0], s[1]}), std::min(distance(p, simplex{s[1], s[2]}), distance(p, simplex{s[2], s[0]})));
|
||||
}
|
||||
|
||||
template <typename T, typename Iterator>
|
||||
std::pair<T, vector<T, 2>> signed_polygon_distance_direction(point<T, 2> const & p, Iterator begin, Iterator end)
|
||||
{
|
||||
std::pair<T, vector<T, 2>> result{limits<T>::max(), vector<T, 2>::zero()};
|
||||
|
||||
for (auto it = begin; it < end; ++it)
|
||||
{
|
||||
auto v = p - *it;
|
||||
auto l = length(v);
|
||||
if (make_min(result.first, l))
|
||||
result.second = v / l;
|
||||
}
|
||||
|
||||
for (auto it = begin, prev = std::prev(end); it != end; prev = it++)
|
||||
{
|
||||
auto v = p - *prev;
|
||||
auto r = *it - *prev;
|
||||
auto t = geom::dot(v, r) / geom::dot(r, r);
|
||||
|
||||
if (0 <= t && t <= 1)
|
||||
{
|
||||
v -= r * t;
|
||||
auto l = length(v);
|
||||
if (make_min(result.first, l))
|
||||
result.second = v / l;
|
||||
}
|
||||
}
|
||||
|
||||
if (polygon_contains(begin, end, p))
|
||||
{
|
||||
result.first = -result.first;
|
||||
result.second = -result.second;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, typename Polygon>
|
||||
std::pair<T, vector<T, 2>> signed_polygon_distance_direction(point<T, 2> const & p, Polygon const & polygon)
|
||||
{
|
||||
return signed_polygon_distance_direction(p, util::begin(polygon), util::end(polygon));
|
||||
}
|
||||
|
||||
template <typename T, typename Iterator>
|
||||
T signed_polygon_distance(point<T, 2> const & p, Iterator begin, Iterator end)
|
||||
{
|
||||
return signed_polygon_distance_direction(p, begin, end).first;
|
||||
}
|
||||
|
||||
template <typename T, typename Polygon>
|
||||
T signed_polygon_distance(point<T, 2> const & p, Polygon const & polygon)
|
||||
{
|
||||
return signed_polygon_distance(p, util::begin(polygon), util::end(polygon));
|
||||
}
|
||||
|
||||
template <typename T, typename Iterator>
|
||||
T polygon_distance(point<T, 2> const & p, Iterator begin, Iterator end)
|
||||
{
|
||||
return std::max(T{0}, signed_polygon_distance(p, begin, end));
|
||||
}
|
||||
|
||||
template <typename T, typename Polygon>
|
||||
T polygon_distance(point<T, 2> const & p, Polygon const & polygon)
|
||||
{
|
||||
return polygon_distance(p, util::begin(polygon), util::end(polygon));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue