Skip to content

Commit e42c4d5

Browse files
Add euclidean distance function to Point class
Calculate the euclidean distance to the origin or another point, avoiding overflows when all element types are unsigned.
1 parent 199cc6b commit e42c4d5

1 file changed

Lines changed: 22 additions & 0 deletions

File tree

libs/common/include/Point.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,28 @@ struct Point //-V690
9898
static constexpr Point all(const T value) noexcept { return Point(value, value); }
9999
constexpr bool isValid() const noexcept { return *this != Invalid(); }
100100

101+
/// Calculate the euclidean distance to the origin
102+
constexpr auto distance() const noexcept { return std::hypot(x, y); }
103+
104+
/// Calculate the euclidean distance to another point
105+
template<typename U, std::enable_if_t<!(std::is_unsigned<T>::value && std::is_unsigned<U>::value), int> = 0>
106+
constexpr auto distance(const Point<U>& pt) const noexcept
107+
{
108+
using Res = ::detail::mixed_type_t<T, U>;
109+
return std::hypot(static_cast<Res>(x) - static_cast<Res>(pt.x), static_cast<Res>(y) - static_cast<Res>(pt.y));
110+
}
111+
112+
/// Calculate the euclidean distance to another point
113+
template<typename U, std::enable_if_t<std::is_unsigned<T>::value && std::is_unsigned<U>::value, int> = 0>
114+
constexpr auto distance(const Point<U>& pt) const noexcept
115+
{
116+
using Res = ::detail::mixed_type_t<T, U>;
117+
const auto x1 = static_cast<Res>(x), x2 = static_cast<Res>(pt.x);
118+
const auto y1 = static_cast<Res>(y), y2 = static_cast<Res>(pt.y);
119+
// Calculate difference of usigned values without overflow
120+
return std::hypot((x1 > x2 ? x1 - x2 : x2 - x1), (y1 > y2 ? y1 - y2 : y2 - y1));
121+
}
122+
101123
constexpr bool operator==(const Point& second) const noexcept;
102124
constexpr bool operator!=(const Point& second) const noexcept;
103125

0 commit comments

Comments
 (0)