From eb2b85c4f6511ac5d44669c6254e971926a6e7c9 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Wed, 18 Apr 2018 21:44:36 +1000 Subject: [PATCH] point: add query for furthest pair --- point.cpp | 29 +++++++++++++++++++++ point.hpp | 69 ++++++++++++++++++++++++++++++++------------------ test/point.cpp | 18 +++++++++++++ 3 files changed, 91 insertions(+), 25 deletions(-) diff --git a/point.cpp b/point.cpp index d4730efd..66cf1cb4 100644 --- a/point.cpp +++ b/point.cpp @@ -38,10 +38,39 @@ namespace util::debug { } +/////////////////////////////////////////////////////////////////////////////// +template +std::pair< + util::point, + util::point +> +util::furthest (util::view*> src) +{ + CHECK_GE (src.size (), 2u); + + auto a = 0; + auto b = 1; + auto d = distance2 (src[a],src[b]); + + for (size_t i = 0; i < src.size (); ++i) { + for (size_t j = i + 1; j < src.size (); ++j) { + if (auto d2 = distance2 (src[i], src[j]); d2 > d) { + a = i; + b = j; + d = d2; + } + } + } + + return { src[a], src[b] }; +} + + //----------------------------------------------------------------------------- #define INSTANTIATE_S_T(S,T) \ template struct util::point; \ template bool util::debug::is_valid (const point&); \ +template std::pair,util::point> util::furthest (util::view*>); \ template struct util::debug::validator>; #define INSTANTIATE(T) \ diff --git a/point.hpp b/point.hpp index 100ebfe8..01e2be12 100644 --- a/point.hpp +++ b/point.hpp @@ -20,6 +20,7 @@ #include "vector.hpp" #include "coord.hpp" #include "maths.hpp" +#include "view.hpp" #include #include @@ -83,6 +84,35 @@ namespace util { void sanity (void) const; }; + + // Convenience typedefs + template using point1 = point<1,T>; + template using point2 = point<2,T>; + template using point3 = point<3,T>; + template using point4 = point<4,T>; + + template using pointi = point; + template using pointf = point; + + typedef point1 point1f; + typedef point2 point2f; + typedef point3 point3f; + typedef point4 point4f; + + typedef point2 point2d; + typedef point3 point3d; + typedef point4 point4d; + + typedef point1 point1u; + typedef point2 point2u; + typedef point3 point3u; + typedef point4 point4u; + + typedef point2 point2i; + typedef point3 point3i; + typedef point4 point4i; + + /////////////////////////////////////////////////////////////////////////// // distance operators @@ -158,32 +188,21 @@ namespace util { return util::max (abs (a - b)); } - // Convenience typedefs - template using point1 = point<1,T>; - template using point2 = point<2,T>; - template using point3 = point<3,T>; - template using point4 = point<4,T>; - template using pointi = point; - template using pointf = point; - - typedef point1 point1f; - typedef point2 point2f; - typedef point3 point3f; - typedef point4 point4f; - - typedef point2 point2d; - typedef point3 point3d; - typedef point4 point4d; - - typedef point1 point1u; - typedef point2 point2u; - typedef point3 point3u; - typedef point4 point4u; - - typedef point2 point2i; - typedef point3 point3i; - typedef point4 point4i; + /////////////////////////////////////////////////////////////////////////// + // returns the most distant pair of points in a set + // + // performance has no guarantees. in fact it's probably spectacularly slow. + // + // especially given we have nothing to accelerate lookups with. if you + // want it to be fast it may be an idea to construct a bounding volume and + // pass those vertices instead. + template + std::pair< + util::point, + util::point + > + furthest (util::view*>); } #endif // __UTIL_POINT_HPP diff --git a/test/point.cpp b/test/point.cpp index 93c8c69c..67dfd5b6 100644 --- a/test/point.cpp +++ b/test/point.cpp @@ -3,6 +3,7 @@ #include "debug.hpp" #include "tap.hpp" #include "types.hpp" +#include "coord/iostream.hpp" using namespace util; @@ -89,5 +90,22 @@ main (void) tap.expect_eq (chebyshev (a, b), 8.f, "chebyshev"); } + // test furthest point calculation + { + util::point2f const cloud[] = { + { 0, 0}, + {-1, 2}, + { 9,-3}, + { 6, 1}, + }; + + auto const i = 1, j = 2; + auto const [a,b] = furthest (util::view{cloud}); + + tap.expect ((a == cloud[i] && b == cloud[j]) || + (b == cloud[i] && a == cloud[j]), + "furthest point test"); + }; + return tap.status (); }