Improve the non-robust geom::in_circle predicate and generalize to any directions

This commit is contained in:
Nikita Lisitsa 2022-09-16 17:56:11 +03:00
parent 30546a505e
commit 46458abd71

View file

@ -13,22 +13,31 @@
namespace psemek::geom namespace psemek::geom
{ {
template <typename T> template <typename T, std::size_t N, typename ... Points>
#ifdef PSEMEK_GEOM_ROBUST_PREDICATES #ifdef PSEMEK_GEOM_ROBUST_PREDICATES
std::enable_if_t<!std::is_floating_point_v<T>, sign_t> std::enable_if_t<!std::is_floating_point_v<T>, sign_t>
#else #else
sign_t sign_t
#endif #endif
in_circle(point<T, 2> const & p0, point<T, 2> const & p1, point<T, 2> const & p2, point<T, 2> const & p3) in_circle(point<T, N> const & p0, Points const & ... points)
{ {
auto proj = [](point<T, 2> const & p) auto proj = [](vector<T, N> const & v)
{ {
auto const x = p[0]; vector<T, N + 1> u;
auto const y = p[1]; u[N] = T{0};
return point<T, 3>{ x, y, x*x + y*y }; for (std::size_t i = 0; i < N; ++i)
{
u[i] = v[i];
u[N] += v[i] * v[i];
}
return u;
}; };
return orientation(proj(p0), proj(p1), proj(p2), proj(p3)); auto result = orientation(proj(points - p0) ...);
if constexpr ((N % 2) == 0)
return inverse(result);
else
return result;
} }
#ifdef PSEMEK_GEOM_ROBUST_PREDICATES #ifdef PSEMEK_GEOM_ROBUST_PREDICATES