From 9b548e56d911e90631e3963d5225ea629705e178 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Mon, 1 Jun 2015 15:29:24 +1000 Subject: [PATCH] point: convert distance member functions to functions --- bezier.cpp | 26 ++++++------ noise/basis/worley.cpp | 4 +- point.hpp | 18 ++++++--- point.ipp | 90 +++++++++++++++++++++--------------------- test/point.cpp | 14 ++++++- 5 files changed, 90 insertions(+), 62 deletions(-) diff --git a/bezier.cpp b/bezier.cpp index 8ea0900f..97bc899a 100644 --- a/bezier.cpp +++ b/bezier.cpp @@ -105,16 +105,16 @@ namespace util { auto c1 = dot (w, v); if (c1 <= 0) - return m_points[0].distance (target); + return util::distance (target, m_points[0]); auto c2 = dot (v, v); if (c2 <= c1) - return m_points[1].distance (target); + return util::distance (target, m_points[1]); auto b = c1 / c2; auto p = m_points[0] + b * v; - return p.distance (target); + return util::distance (target, p); } } @@ -271,12 +271,12 @@ namespace util { continue; if (t <= 0) - dist = min (dist, p0.distance (target)); + dist = min (dist, util::distance (target, p0)); else if (t > 1) - dist = min (p2.distance (target)); + dist = min (util::distance (target, p2)); else { auto p = eval (t); - dist = min (dist, p.distance (target)); + dist = min (dist, util::distance (target, p)); } } @@ -303,8 +303,8 @@ float refine_cubic (util::bezier<3> b, util::point2f p_l = b.eval (t_l); util::point2f p_r = b.eval (t_r); - float d_l = p_l.distance (target); - float d_r = p_r.distance (target); + float d_l = util::distance (target, p_l); + float d_r = util::distance (target, p_r); if (d_l < d) { return refine_cubic (b, target, t_l, d_l, p); } if (d_r < d) { return refine_cubic (b, target, t_r, d_r, p); } @@ -327,14 +327,18 @@ namespace util { lookup[i] = eval (i / float (SUBDIV - 1)); size_t best = 0; - for (size_t i = 1; i < lookup.size (); ++i) - if (lookup[i].distance2 (target) < lookup[best].distance2 (target)) + for (size_t i = 1; i < lookup.size (); ++i) { + auto d_i = util::distance2 (target, lookup[i]); + auto d_b = util::distance2 (target, lookup[best]); + + if (d_i < d_b) best = i; + } return refine_cubic (*this, target, best / float (SUBDIV - 1), - lookup[best].distance (target), + util::distance (target, lookup[best]), 1.f / SUBDIV); } } diff --git a/noise/basis/worley.cpp b/noise/basis/worley.cpp index f5ead63c..bf0ef8bc 100644 --- a/noise/basis/worley.cpp +++ b/noise/basis/worley.cpp @@ -100,8 +100,10 @@ worley::operator() (util::point<2,T> p) const CHECK (off.y >= 0 && off.y <= 1); pos += off; - *cursor++ = pos.difference2 (p_rem.template as ()); + *cursor = distance2 (pos + off, p_rem); + cursor++; } + } std::sort (std::begin (distances), std::end (distances)); CHECK_GE (distances[0], 0); diff --git a/point.hpp b/point.hpp index bc40e09a..4228b691 100644 --- a/point.hpp +++ b/point.hpp @@ -33,11 +33,6 @@ namespace util { { using coord::base::base; - // point operators - template typename std::common_type::type distance (point) const; - template typename std::common_type::type distance2 (point) const; - template typename std::common_type::type manhattan (point) const; - vector to (point) const; vector from (point) const; @@ -48,6 +43,19 @@ namespace util { void sanity (void) const; }; + // distance operators + template + typename std::common_type::type distance (point, point); + + template + typename std::common_type::type distance2 (point, point); + + template + typename std::common_type::type manhattan (point, point); + + template + typename std::common_type::type chebyshev (point, point); + // iostream operators template std::ostream& operator<< (std::ostream&, point); diff --git a/point.ipp b/point.ipp index dba6dadd..e2dd343a 100644 --- a/point.ipp +++ b/point.ipp @@ -19,50 +19,6 @@ #include namespace util { - //------------------------------------------------------------------------- - template - template - typename std::common_type::type - util::point::distance (point rhs) const - { - return std::sqrt (distance2 (rhs)); - } - - - //------------------------------------------------------------------------- - template - template - typename std::common_type::type - util::point::distance2 (point rhs) const - { - typedef typename std::common_type::type result_t; - - result_t sum { 0 }; - - for (size_t i = 0; i < S; ++i) - sum += pow2 (this->data[i] - rhs.data[i]); - - return sum; - } - - - //------------------------------------------------------------------------- - template - template - typename std::common_type::type - util::point::manhattan (point rhs) const - { - typedef typename std::common_type::type result_t; - - result_t sum { 0 }; - - for (size_t i = 0; i < S; ++i) - sum += std::abs (this->data[i] - rhs.data[i]); - - return sum; - } - - ///------------------------------------------------------------------------ /// expand point to use homogenous coordinates of a higher dimension. /// ie, fill with (0,..,0,1) @@ -88,4 +44,50 @@ namespace util { return out; } + + + //------------------------------------------------------------------------- + template + typename std::common_type::type + distance (point a, point b) + { + return std::sqrt (distance2 (a, b)); + } + + + //------------------------------------------------------------------------- + template + 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 + manhattan (point a, point b) + { + typename std::common_type::type sum {0}; + + for (size_t i = 0; i < S; ++i) + sum += std::abs (a.data[i] - b.data[i]); + + return sum; + } + + + //------------------------------------------------------------------------- + template + typename std::common_type::type + chebyshev(point a, point b) + { + return util::max (abs (a - b)); + } } diff --git a/test/point.cpp b/test/point.cpp index 4faa972a..e022b5a9 100644 --- a/test/point.cpp +++ b/test/point.cpp @@ -47,6 +47,7 @@ main (int, char**) { CHECK_EQ (pf.template cast (), pu); } + // redim to 4-dimension homogenous coords { const point2f p (3, 4); const point4f q = p.homog<4> (); @@ -57,6 +58,17 @@ main (int, char**) { CHECK_EQ (q.w, 1); } + // trivial checks for distance metrics + { + const point2f a (1, 2); + const point2f b (9, 5); + + CHECK_EQ (distance2 (a, b), 73.f); + CHECK_EQ (distance (a, b), std::sqrt (73.f)); + CHECK_EQ (manhattan (a, b), 11.f); + CHECK_EQ (chebyshev (a, b), 8.f); + } + util::TAP::logger tap; - tap.todo ("convert to TAP"); + tap.skip ("convert to TAP"); }