Create distance measures for the orthogonal grids

This commit is contained in:
James P. Howard, II
2022-08-24 13:45:39 -04:00
parent 922572973d
commit 972e83aeeb
5 changed files with 103 additions and 2 deletions

View File

@@ -110,7 +110,30 @@ namespace kami {
*
* @details All gridded coordinates are expected to subclass `GridCoord`.
*/
class LIBKAMI_EXPORT GridCoord : public Coord {};
class LIBKAMI_EXPORT GridCoord : public Coord {
public:
/**
* @brief Find the distance between two points
*
* @details Find the distance between two points using the
* specified metric. There are three options provided by
* the `GridDistanceType` class.
*
* However, the coordinate class is not aware of the
* properties of the `GridDomain` it is operating on. Accordingly,
* if the direct path is measured, without accounting for
* and toroidal wrapping of the underlying `GridDomain`.
*
* @param p the point to measure the distance to
* @param distance_type specify the distance type
*
* @returns the distance as a `double`
*/
virtual std::optional<double> distance(std::shared_ptr<Coord> &p, GridDistanceType distance_type) const = 0;
};
} // namespace kami

View File

@@ -64,6 +64,28 @@ namespace kami {
*/
[[nodiscard]] std::string to_string() const override;
/**
* @brief Find the distance between two points
*
* @details Find the distance between two points using the
* specified metric. There are three options provided by
* the `GridDistanceType` class. However, of the three
* distance types provided, all provide the same result so
* the value is ignored and the single result is returned.
*
* However, the coordinate class is not aware of the
* properties of the `Grid1D` it is operating on. Accordingly,
* if the direct path is measured, without accounting for
* and toroidal wrapping of the underlying `Grid1D`.
*
* @param p the point to measure the distance to
* @param distance_type specify the distance type
*
* @returns the distance as a `double`
*/
std::optional<double>
distance(std::shared_ptr<Coord> &p, [[maybe_unused]] GridDistanceType distance_type) const override;
/**
* @brief Test if two coordinates are equal
*/

View File

@@ -29,6 +29,8 @@
#define KAMI_GRID2D_H
//! @endcond
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <map>
#include <memory>
@@ -46,12 +48,25 @@ namespace kami {
* @brief Two-dimensional coordinates
*/
class LIBKAMI_EXPORT GridCoord2D : public GridCoord {
protected:
inline double distance_chebyshev(std::shared_ptr<GridCoord2D> &p) const {
return static_cast<double>(fmax(abs(_x_coord - p->_x_coord), abs(_x_coord - p->_x_coord)));
};
inline double distance_euclidean(std::shared_ptr<GridCoord2D> &p) const {
return sqrt(pow(_x_coord - p->_x_coord, 2) + pow(_x_coord - p->_x_coord, 2));
};
inline double distance_manhattan(std::shared_ptr<GridCoord2D> &p) const {
return static_cast<double>(abs(_x_coord - p->_x_coord) + abs(_x_coord - p->_x_coord));
};
public:
/**
* @brief Constructor for two-dimensional coordinates
*/
GridCoord2D(int x_coord, int y_coord)
: _x_coord(x_coord), _y_coord(y_coord){};
: _x_coord(x_coord), _y_coord(y_coord) {};
/**
* @brief Get the coordinate in the first dimension or `x`.
@@ -70,6 +85,25 @@ namespace kami {
*/
[[nodiscard]] std::string to_string() const override;
/**
* @brief Find the distance between two points
*
* @details Find the distance between two points using the
* specified metric. There are three options provided by
* the `GridDistanceType` class.
*
* However, the coordinate class is not aware of the
* properties of the `Grid2D` it is operating on. Accordingly,
* if the direct path is measured, without accounting for
* and toroidal wrapping of the underlying `Grid2D`.
*
* @param p the point to measure the distance to
* @param distance_type specify the distance type
*
* @returns the distance as a `double`
*/
std::optional<double> distance(std::shared_ptr<Coord> &p, GridDistanceType distance_type) const override;
/**
* @brief Test if two coordinates are equal
*/

View File

@@ -45,6 +45,14 @@ namespace kami {
return std::string("(" + std::to_string(_x_coord) + ")");
}
std::optional<double>
GridCoord1D::distance(std::shared_ptr<Coord> &p, [[maybe_unused]] GridDistanceType distance_type) const {
// We are going to ignore distance type since they all
// have the same result in one dimension.
auto p1d = std::static_pointer_cast<GridCoord1D>(p);
return static_cast<double>(abs(_x_coord - p1d->_x_coord));
}
bool operator==(const GridCoord1D &lhs, const GridCoord1D &rhs) {
return (lhs._x_coord == rhs._x_coord);
}

View File

@@ -48,6 +48,20 @@ namespace kami {
return std::string("(" + std::to_string(_x_coord) + ", " + std::to_string(_y_coord) + ")");
}
std::optional<double> GridCoord2D::distance(std::shared_ptr<Coord> &p, GridDistanceType distance_type) const {
auto p2d = std::static_pointer_cast<GridCoord2D>(p);
switch (distance_type) {
case GridDistanceType::Chebyshev:
return distance_chebyshev(p2d);
case GridDistanceType::Manhattan:
return distance_manhattan(p2d);
case GridDistanceType::Euclidean:
return distance_euclidean(p2d);
}
return std::nullopt;
}
bool operator==(const GridCoord2D &lhs, const GridCoord2D &rhs) {
return (lhs._x_coord == rhs._x_coord && lhs._y_coord == rhs._y_coord);
}