Add a CMake option for robust geom predicates

This commit is contained in:
Nikita Lisitsa 2020-09-14 15:30:09 +03:00
parent d250becf43
commit c87a8a5c71
3 changed files with 27 additions and 3 deletions

View file

@ -1,9 +1,17 @@
find_package(Boost REQUIRED) option(PSEMEK_GEOM_ROBUST_PREDICATES "Use robust geometric predicates" OFF)
find_package(GMP REQUIRED)
if(PSEMEK_GEOM_ROBUST_PREDICATES)
find_package(Boost REQUIRED)
find_package(GMP REQUIRED)
endif()
file(GLOB_RECURSE PSEMEK_GEOM_HEADERS "include/*.hpp") file(GLOB_RECURSE PSEMEK_GEOM_HEADERS "include/*.hpp")
file(GLOB_RECURSE PSEMEK_GEOM_SOURCES "source/*.cpp") file(GLOB_RECURSE PSEMEK_GEOM_SOURCES "source/*.cpp")
add_library(geom ${PSEMEK_GEOM_HEADERS} ${PSEMEK_GEOM_SOURCES}) add_library(geom ${PSEMEK_GEOM_HEADERS} ${PSEMEK_GEOM_SOURCES})
target_include_directories(geom PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") target_include_directories(geom PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(geom PUBLIC util Boost::boost GMP) target_link_libraries(geom PUBLIC util)
if(PSEMEK_GEOM_ROBUST_PREDICATES)
target_link_libraries(geom PUBLIC Boost::boost GMP)
target_compile_definitions(geom PUBLIC -DPSEMEK_GEOM_ROBUST_PREDICATES=1)
endif()

View file

@ -4,7 +4,9 @@
#include <psemek/geom/point.hpp> #include <psemek/geom/point.hpp>
#include <psemek/geom/orientation.hpp> #include <psemek/geom/orientation.hpp>
#ifdef PSEMEK_GEOM_ROBUST_PREDICATES
#include <boost/multiprecision/gmp.hpp> #include <boost/multiprecision/gmp.hpp>
#endif
#include <type_traits> #include <type_traits>
@ -12,7 +14,11 @@ namespace psemek::geom
{ {
template <typename T> template <typename T>
#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
sign_t
#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, 2> const & p0, point<T, 2> const & p1, point<T, 2> const & p2, point<T, 2> const & p3)
{ {
auto proj = [](point<T, 2> const & p) auto proj = [](point<T, 2> const & p)
@ -25,6 +31,7 @@ namespace psemek::geom
return orientation(proj(p0), proj(p1), proj(p2), proj(p3)); return orientation(proj(p0), proj(p1), proj(p2), proj(p3));
} }
#ifdef PSEMEK_GEOM_ROBUST_PREDICATES
template <typename T> template <typename T>
std::enable_if_t<std::is_floating_point_v<T>, sign_t> std::enable_if_t<std::is_floating_point_v<T>, sign_t>
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, 2> const & p0, point<T, 2> const & p1, point<T, 2> const & p2, point<T, 2> const & p3)
@ -67,5 +74,6 @@ namespace psemek::geom
return in_circle(cast<exact_type>(p0), cast<exact_type>(p1), cast<exact_type>(p2), cast<exact_type>(p3)); return in_circle(cast<exact_type>(p0), cast<exact_type>(p1), cast<exact_type>(p2), cast<exact_type>(p3));
} }
} }
#endif
} }

View file

@ -4,7 +4,9 @@
#include <psemek/geom/point.hpp> #include <psemek/geom/point.hpp>
#include <psemek/geom/sign.hpp> #include <psemek/geom/sign.hpp>
#ifdef PSEMEK_GEOM_ROBUST_PREDICATES
#include <boost/multiprecision/gmp.hpp> #include <boost/multiprecision/gmp.hpp>
#endif
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
@ -14,7 +16,11 @@ namespace psemek::geom
// TODO: generic implementation // TODO: generic implementation
template <typename T> template <typename T>
#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
sign_t
#endif
orientation(point<T, 2> const & p0, point<T, 2> const & p1, point<T, 2> const & p2) orientation(point<T, 2> const & p0, point<T, 2> const & p1, point<T, 2> const & p2)
{ {
T const d = det(p1 - p0, p2 - p0); T const d = det(p1 - p0, p2 - p0);
@ -27,6 +33,7 @@ namespace psemek::geom
return sign_t::zero; return sign_t::zero;
} }
#ifdef PSEMEK_GEOM_ROBUST_PREDICATES
template <typename T> template <typename T>
std::enable_if_t<std::is_floating_point_v<T>, sign_t> std::enable_if_t<std::is_floating_point_v<T>, sign_t>
orientation(point<T, 2> const & p0, point<T, 2> const & p1, point<T, 2> const & p2) orientation(point<T, 2> const & p0, point<T, 2> const & p1, point<T, 2> const & p2)
@ -50,6 +57,7 @@ namespace psemek::geom
return orientation(cast<exact_type>(p0), cast<exact_type>(p1), cast<exact_type>(p2)); return orientation(cast<exact_type>(p0), cast<exact_type>(p1), cast<exact_type>(p2));
} }
} }
#endif
template <typename T> template <typename T>
sign_t orientation(point<T, 3> const & p0, point<T, 3> const & p1, point<T, 3> const & p2, point<T, 3> const & p3) sign_t orientation(point<T, 3> const & p0, point<T, 3> const & p1, point<T, 3> const & p2, point<T, 3> const & p3)