Add crude point-convex body distance to cg
This commit is contained in:
parent
d179ef65a2
commit
47d3156c57
1 changed files with 70 additions and 0 deletions
70
libs/cg/include/psemek/cg/convex/distance.hpp
Normal file
70
libs/cg/include/psemek/cg/convex/distance.hpp
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <psemek/cg/body/body.hpp>
|
||||||
|
#include <psemek/geom/interval.hpp>
|
||||||
|
#include <psemek/geom/math.hpp>
|
||||||
|
|
||||||
|
namespace psemek::cg
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename Body, typename T>
|
||||||
|
T distance_fast_2d(Body const & b, geom::point<T, 2> const & p)
|
||||||
|
{
|
||||||
|
T result = geom::limits<T>::min();
|
||||||
|
|
||||||
|
auto const & vs = vertices(b);
|
||||||
|
|
||||||
|
for (auto const & e : edges(b))
|
||||||
|
{
|
||||||
|
auto n = geom::ort(geom::normalized(vs[e[0]] - vs[e[1]]));
|
||||||
|
geom::make_max(result, geom::dot(n, p - vs[e[0]]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Body, typename T>
|
||||||
|
T distance_fast_3d(Body const & b, geom::point<T, 3> const & p)
|
||||||
|
{
|
||||||
|
T result = geom::limits<T>::min();
|
||||||
|
|
||||||
|
auto const & vs = vertices(b);
|
||||||
|
|
||||||
|
for (auto const & f : faces(b))
|
||||||
|
{
|
||||||
|
auto n = geom::normal(vs[f[0]], vs[f[1]], vs[f[2]]);
|
||||||
|
geom::make_max(result, geom::dot(n, p - vs[f[0]]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns an upper bound of the distance between b and p
|
||||||
|
// using only edge/face normals
|
||||||
|
template <typename Body, typename Point>
|
||||||
|
auto distance_fast(Body const & b, Point const & p)
|
||||||
|
{
|
||||||
|
constexpr auto dim = dimension<Body>;
|
||||||
|
|
||||||
|
static_assert(dim == 2 || dim == 3);
|
||||||
|
|
||||||
|
if constexpr (dim == 2)
|
||||||
|
{
|
||||||
|
return detail::distance_fast_2d(b, p);
|
||||||
|
}
|
||||||
|
else if constexpr (dim == 3)
|
||||||
|
{
|
||||||
|
return detail::distance_fast_3d(b, p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue