point: add query for furthest pair

This commit is contained in:
Danny Robson 2018-04-18 21:44:36 +10:00
parent 5ba9da1828
commit eb2b85c4f6
3 changed files with 91 additions and 25 deletions

View File

@ -38,10 +38,39 @@ namespace util::debug {
}
///////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T>
std::pair<
util::point<S,T>,
util::point<S,T>
>
util::furthest (util::view<const util::point<S,T>*> 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<S,T>; \
template bool util::debug::is_valid (const point<S,T>&); \
template std::pair<util::point<S,T>,util::point<S,T>> util::furthest (util::view<const util::point<S,T>*>); \
template struct util::debug::validator<point<S,T>>;
#define INSTANTIATE(T) \

View File

@ -20,6 +20,7 @@
#include "vector.hpp"
#include "coord.hpp"
#include "maths.hpp"
#include "view.hpp"
#include <algorithm>
#include <type_traits>
@ -83,6 +84,35 @@ namespace util {
void sanity (void) const;
};
// Convenience typedefs
template <typename T> using point1 = point<1,T>;
template <typename T> using point2 = point<2,T>;
template <typename T> using point3 = point<3,T>;
template <typename T> using point4 = point<4,T>;
template <size_t S> using pointi = point<S,int>;
template <size_t S> using pointf = point<S,float>;
typedef point1<float> point1f;
typedef point2<float> point2f;
typedef point3<float> point3f;
typedef point4<float> point4f;
typedef point2<double> point2d;
typedef point3<double> point3d;
typedef point4<double> point4d;
typedef point1<unsigned> point1u;
typedef point2<unsigned> point2u;
typedef point3<unsigned> point3u;
typedef point4<unsigned> point4u;
typedef point2<int> point2i;
typedef point3<int> point3i;
typedef point4<int> point4i;
///////////////////////////////////////////////////////////////////////////
// distance operators
@ -158,32 +188,21 @@ namespace util {
return util::max (abs (a - b));
}
// Convenience typedefs
template <typename T> using point1 = point<1,T>;
template <typename T> using point2 = point<2,T>;
template <typename T> using point3 = point<3,T>;
template <typename T> using point4 = point<4,T>;
template <size_t S> using pointi = point<S,int>;
template <size_t S> using pointf = point<S,float>;
typedef point1<float> point1f;
typedef point2<float> point2f;
typedef point3<float> point3f;
typedef point4<float> point4f;
typedef point2<double> point2d;
typedef point3<double> point3d;
typedef point4<double> point4d;
typedef point1<unsigned> point1u;
typedef point2<unsigned> point2u;
typedef point3<unsigned> point3u;
typedef point4<unsigned> point4u;
typedef point2<int> point2i;
typedef point3<int> point3i;
typedef point4<int> 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 <size_t S, typename T>
std::pair<
util::point<S,T>,
util::point<S,T>
>
furthest (util::view<const util::point<S,T>*>);
}
#endif // __UTIL_POINT_HPP

View File

@ -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 ();
}