steiner_tree/
point.rs

1// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5use num_traits::{Signed, Zero};
6use std::ops::{Add, Sub};
7
8/// Point in the Euclidean plane.
9#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)]
10pub struct Point<T> {
11    /// x coordinate.
12    pub x: T,
13    /// y coordinate.
14    pub y: T,
15}
16
17impl<T> Point<T> {
18    /// Create a new point.
19    pub fn new(x: T, y: T) -> Self {
20        Self { x, y }
21    }
22}
23
24impl<T> Point<T>
25where
26    T: Copy + Add<Output = T> + Sub<Output = T> + Zero,
27{
28    /// Rotate the point around the origin by 90 degrees counter-clock-wise.
29    pub fn rotate_ccw90(&self) -> Self {
30        Self::new(T::zero() - self.y, self.x)
31    }
32}
33
34impl<T> Point<T>
35where
36    T: Copy + Add<Output = T> + Sub<Output = T> + Signed,
37{
38    /// Compute the manhattan distance between both points.
39    pub fn manhattan_distance(&self, other: &Self) -> T {
40        let dx = self.x - other.x;
41        let dy = self.y - other.y;
42
43        dx.abs() + dy.abs()
44    }
45
46    /// Shift the point.
47    pub fn translate(&self, (dx, dy): (T, T)) -> Self {
48        Point::new(self.x + dx, self.y + dy)
49    }
50}
51
52impl<T> From<(T, T)> for Point<T> {
53    fn from((x, y): (T, T)) -> Self {
54        Point::new(x, y)
55    }
56}