Skip to content

Commit 3bc678a

Browse files
committed
Added the LInf metric.
Documentation updated.
1 parent d3ba535 commit 3bc678a

File tree

5 files changed

+69
-19
lines changed

5 files changed

+69
-19
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ KdTree:
2929
* Nearest neighbor, approximate nearest neighbor, radius, box, and customizable nearest neighbor searches.
3030
* [Metrics](https://en.wikipedia.org/wiki/Metric_(mathematics)):
3131
* Support for topological spaces with identifications. E.g., points on the circle `[-pi, pi]`.
32-
* Available metrics: `L1`, `L2Squared`, `SO2`, and `SE2Squared`. Metrics can be customized.
32+
* Available metrics: `L1`, `L2Squared`, `LInf`, `SO2`, and `SE2Squared`. Metrics can be customized.
3333
* Multiple tree splitting rules: `kLongestMedian`, `kMidpoint` and `kSlidingMidpoint`.
3434
* Compile time and run time known dimensions.
3535
* Static tree builds.
@@ -51,8 +51,8 @@ PicoTree can interface with different types of points and point sets through tra
5151

5252
# Examples
5353

54-
* [Minimal working example](./examples/kd_tree/kd_tree_minimal.cpp) using an `std::vector<>` of points.
55-
* [Creating a KdTree](./examples/kd_tree/kd_tree_creation.cpp) and taking the input by value or reference.
54+
* [Minimal working example](./examples/kd_tree/kd_tree_minimal.cpp) for building and querying a KdTree.
55+
* [Creating a KdTree](./examples/kd_tree/kd_tree_creation.cpp) and having it take the input by value or reference.
5656
* Using the KdTree's [search](./examples/kd_tree/kd_tree_search.cpp) capabilities.
5757
* Working with [dynamic size arrays](./examples/kd_tree/kd_tree_dynamic_arrays.cpp).
5858
* Supporting a [custom point type](./examples/kd_tree/kd_tree_custom_point_type.cpp).

src/pico_tree/pico_tree/internal/box.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ class BoxBase {
2727
static constexpr SizeType Dim = BoxTraits<Derived>::Dim;
2828
static_assert(Dim == kDynamicSize || Dim > 0, "DIM_MUST_BE_DYNAMIC_OR_>_0");
2929

30-
//! \brief Returns true if \p x is contained. A point on the edge considered
31-
//! inside the box.
30+
//! \brief Returns true if \p x is contained. A point on the edge is
31+
//! considered inside the box.
3232
constexpr bool Contains(ScalarType const* x) const {
3333
// We use derived().size() which includes the constexpr part. Otherwise a
3434
// small trait needs to be written.

src/pico_tree/pico_tree/metric.hpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,41 @@ struct L2Squared {
210210
}
211211
};
212212

213+
struct LInf {
214+
//! \brief This tag specifies the supported space by this metric.
215+
using SpaceTag = EuclideanSpaceTag;
216+
217+
template <
218+
typename InputIterator1,
219+
typename InputSentinel1,
220+
typename InputIterator2>
221+
constexpr auto operator()(
222+
InputIterator1 begin1, InputSentinel1 end1, InputIterator2 begin2) const {
223+
using ScalarType =
224+
typename std::iterator_traits<InputIterator1>::value_type;
225+
226+
ScalarType d{};
227+
228+
for (; begin1 != end1; ++begin1, ++begin2) {
229+
d = std::max(d, internal::Distance(*begin1, *begin2));
230+
}
231+
232+
return d;
233+
}
234+
235+
//! \brief Calculates the distance between two coordinates.
236+
template <typename Scalar_>
237+
constexpr Scalar_ operator()(Scalar_ x, Scalar_ y) const {
238+
return internal::Distance(x, y);
239+
}
240+
241+
//! \brief Returns the absolute value of \p x.
242+
template <typename Scalar_>
243+
constexpr Scalar_ operator()(Scalar_ x) const {
244+
return std::abs(x);
245+
}
246+
};
247+
213248
//! \brief The SO2 metric measures distances on the unit circle S1. It is the
214249
//! intrinsic metric of points in R2 on S1 given by the great-circel distance.
215250
//! \details Named after the Special Orthogonal Group of dimension 2. The circle

src/pico_tree/pico_tree/opencv_traits.hpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,19 @@
88
//! \file opencv_traits.hpp
99
//! \brief Contains traits that provide OpenCV support for PicoTree.
1010
//! \details The following is supported:
11-
//! * std::vector<cv::Point_<>>
12-
//! * std::vector<cv::Point3_<>>
13-
//! * std::vector<cv::Vec_<>>
14-
//! * cv::Mat
11+
//! * cv::Vec_<> as a point type.
12+
//! * cv::Mat as a space type.
1513

1614
namespace pico_tree {
1715

1816
//! \brief PointTraits provides an interface for cv::Point_<>.
17+
//! \details PointTraits<cv::Point_<Scalar_>> violates the strict aliasing rule
18+
//! by interpreting a struct of scalars as an array of scalars and using this
19+
//! specialization is therefore UB. Note that this specialization will work in
20+
//! practice but you have been warned. Don't use it to avoid UB.
1921
template <typename Scalar_>
2022
struct PointTraits<cv::Point_<Scalar_>> {
21-
static_assert(sizeof(cv::Point_<Scalar_>) == (sizeof(Scalar_) * 2), "");
23+
static_assert(sizeof(cv::Point_<Scalar_>) == sizeof(Scalar_[2]), "");
2224

2325
//! \brief Supported point type.
2426
using PointType = cv::Point_<Scalar_>;
@@ -39,9 +41,13 @@ struct PointTraits<cv::Point_<Scalar_>> {
3941
};
4042

4143
//! \brief PointTraits provides an interface for cv::Point3_<>.
44+
//! \details PointTraits<cv::Point3_<Scalar_>> violates the strict aliasing rule
45+
//! by interpreting a struct of scalars as an array of scalars and using this
46+
//! specialization is therefore UB. Note that this specialization will work in
47+
//! practice but you have been warned. Don't use it to avoid UB.
4248
template <typename Scalar_>
4349
struct PointTraits<cv::Point3_<Scalar_>> {
44-
static_assert(sizeof(cv::Point3_<Scalar_>) == (sizeof(Scalar_) * 3), "");
50+
static_assert(sizeof(cv::Point3_<Scalar_>) == sizeof(Scalar_[3]), "");
4551

4652
//! \brief Supported point type.
4753
using PointType = cv::Point3_<Scalar_>;

test/pico_tree/metric_test.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
#include <pico_tree/metric.hpp>
66
#include <pico_understory/metric.hpp>
77

8-
using PointX = Point2f;
9-
108
template <typename Metric_, typename P0, typename P1>
119
inline auto Distance(Metric_ const& metric, P0 const& p0, P1 const& p1) {
1210
auto w0 = pico_tree::internal::PointWrapper<P0>(p0);
@@ -15,8 +13,8 @@ inline auto Distance(Metric_ const& metric, P0 const& p0, P1 const& p1) {
1513
}
1614

1715
TEST(MetricTest, L1) {
18-
PointX p0{2.0f, 4.0f};
19-
PointX p1{10.0f, 1.0f};
16+
Point2f p0{2.0f, 4.0f};
17+
Point2f p1{10.0f, 1.0f};
2018

2119
pico_tree::L1 metric;
2220

@@ -26,8 +24,8 @@ TEST(MetricTest, L1) {
2624
}
2725

2826
TEST(MetricTest, L2) {
29-
PointX p0{7.0f, 5.0f};
30-
PointX p1{10.0f, 1.0f};
27+
Point2f p0{7.0f, 5.0f};
28+
Point2f p1{10.0f, 1.0f};
3129

3230
pico_tree::L2 metric;
3331

@@ -37,8 +35,8 @@ TEST(MetricTest, L2) {
3735
}
3836

3937
TEST(MetricTest, L2Squared) {
40-
PointX p0{2.0f, 4.0f};
41-
PointX p1{10.0f, 1.0f};
38+
Point2f p0{2.0f, 4.0f};
39+
Point2f p1{10.0f, 1.0f};
4240

4341
pico_tree::L2Squared metric;
4442

@@ -47,6 +45,17 @@ TEST(MetricTest, L2Squared) {
4745
EXPECT_FLOAT_EQ(metric(-3.1f), 9.61f);
4846
}
4947

48+
TEST(MetricTest, LInf) {
49+
Point2f p0{2.0f, 4.0f};
50+
Point2f p1{10.0f, 1.0f};
51+
52+
pico_tree::LInf metric;
53+
54+
EXPECT_FLOAT_EQ(Distance(metric, p0, p1), 8.0f);
55+
EXPECT_FLOAT_EQ(metric(-3.1f, 8.9f), 12.0f);
56+
EXPECT_FLOAT_EQ(metric(-3.1f), 3.1f);
57+
}
58+
5059
TEST(MetricTest, SO2) {
5160
Point1f p0{1.0f};
5261
Point1f p1{1.1f};

0 commit comments

Comments
 (0)