diff --git a/point.ipp b/point.ipp index 119e150b..38b146f3 100644 --- a/point.ipp +++ b/point.ipp @@ -18,104 +18,102 @@ #include -namespace util { - ///------------------------------------------------------------------------ - /// expand point to use homogenous coordinates of a higher dimension. - /// ie, fill with (0,..,0,1) - template - template - point - point::homog (void) const - { - static_assert (D > S, "homog will not overwrite data"); +///------------------------------------------------------------------------ +/// expand point to use homogenous coordinates of a higher dimension. +/// ie, fill with (0,..,0,1) +template +template +util::point +util::point::homog (void) const +{ + static_assert (D > S, "homog will not overwrite data"); - point out; + point out; - // Copy the existing data - auto c = std::copy (this->begin (), - this->end (), - out.begin ()); + // Copy the existing data + auto c = std::copy (this->begin (), + this->end (), + out.begin ()); - // Fill until the second last element with zeros - auto f = std::fill_n (c, D - S - 1, T{0}); + // Fill until the second last element with zeros + auto f = std::fill_n (c, D - S - 1, T{0}); - // Last element should be one - *f = T{1}; + // Last element should be one + *f = T{1}; - return out; - } - - - //------------------------------------------------------------------------- - template - typename std::common_type::type - distance (point a, point b) - { - using type_t = typename std::common_type::type; - static_assert (std::is_floating_point::value, - "sqrt likely requires fractional types"); - - return std::sqrt (distance2 (a, b)); - } - - - //------------------------------------------------------------------------- - template - constexpr typename std::common_type::type - distance2 (point a, point b) - { - typename std::common_type::type sum {0}; - - for (size_t i = 0; i < S; ++i) - sum += pow2 (a.data[i] - b.data[i]); - - return sum; - } - - - //------------------------------------------------------------------------- - template - typename std::common_type::type - octile (point2 a, point2 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 - manhattan (point a, point b) - { - typename std::common_type::type sum {0}; - - for (size_t i = 0; i < S; ++i) - sum += util::abs (a.data[i] - b.data[i]); - - return sum; - } - - - //------------------------------------------------------------------------- - template - constexpr typename std::common_type::type - chebyshev(point a, point b) - { - return util::max (abs (a - b)); - } + return out; +} + + +//------------------------------------------------------------------------- +template +typename std::common_type::type +util::distance (point a, point b) +{ + using type_t = typename std::common_type::type; + static_assert (std::is_floating_point::value, + "sqrt likely requires fractional types"); + + return std::sqrt (distance2 (a, b)); +} + + +//------------------------------------------------------------------------- +template +constexpr typename std::common_type::type +util::distance2 (point a, point b) +{ + typename std::common_type::type sum {0}; + + for (size_t i = 0; i < S; ++i) + sum += pow2 (a.data[i] - b.data[i]); + + return sum; +} + + +//------------------------------------------------------------------------- +template +typename std::common_type::type +util::octile (point2 a, point2 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 +util::manhattan (point a, point b) +{ + typename std::common_type::type sum {0}; + + for (size_t i = 0; i < S; ++i) + sum += util::abs (a.data[i] - b.data[i]); + + return sum; +} + + +//------------------------------------------------------------------------- +template +constexpr typename std::common_type::type +util::chebyshev(point a, point b) +{ + return util::max (abs (a - b)); }