point: add query for furthest pair
This commit is contained in:
parent
5ba9da1828
commit
eb2b85c4f6
29
point.cpp
29
point.cpp
@ -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) \
|
||||
|
69
point.hpp
69
point.hpp
@ -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
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user