From c7637fd6275be41fa3efe5bfc2b21ee52adb2998 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Tue, 22 Sep 2015 18:32:11 +1000 Subject: [PATCH] point: add octile distance function --- point.hpp | 3 +++ point.ipp | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/point.hpp b/point.hpp index ff857d8a..5f437fa4 100644 --- a/point.hpp +++ b/point.hpp @@ -50,6 +50,9 @@ namespace util { template constexpr typename std::common_type::type distance2 (point, point); + template + constexpr typename std::common_type::type octile (point, point); + template constexpr typename std::common_type::type manhattan (point, point); diff --git a/point.ipp b/point.ipp index 6bf7aa44..e816c9c9 100644 --- a/point.ipp +++ b/point.ipp @@ -73,6 +73,30 @@ namespace util { } + //------------------------------------------------------------------------- + template + constexpr typename std::common_type::type + octile (point a, point b) + { + using type_t = typename std::common_type::type; + static_assert (!std::is_integral::value, + "octile requires more than integer precision"); + + const type_t D1 = 1; + const type_t D2 = std::sqrt (type_t {2}); + + auto diff = util::abs (a - b); + + // distance for axis-aligned walks + auto axis = D1 * (diff.x + diff.y); + + // the savings from diagonal walks + auto diag = (D2 - 2 * D1) * util::min (diff); + + return axis + diag; + } + + //------------------------------------------------------------------------- template constexpr typename std::common_type::type