haar_lib/geom_int/
mod.rs

1//! 整数値での幾何
2
3pub mod arg_sort;
4pub mod closest_pair;
5pub mod convex_hull;
6
7use crate::impl_from;
8use crate::impl_ops;
9use std::f64::consts::PI;
10
11/// 整数値をもつ二次元ベクトル
12#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
13pub struct VectorInt {
14    /// x座標
15    pub x: i64,
16    /// y座標
17    pub y: i64,
18}
19
20impl VectorInt {
21    /// 二次元ベクトル(x, y)を返す。
22    pub fn new(x: i64, y: i64) -> Self {
23        Self { x, y }
24    }
25
26    /// 絶対値を計算する
27    pub fn abs(self) -> f64 {
28        let x = self.x as f64;
29        let y = self.y as f64;
30        (x * x + y * y).sqrt()
31    }
32    /// 絶対値の2乗を計算する
33    pub fn abs_sq(self) -> i64 {
34        self.x * self.x + self.y * self.y
35    }
36    /// 内積を計算する
37    pub fn dot(self, other: Self) -> i64 {
38        self.x * other.x + self.y * other.y
39    }
40    /// 外積を計算する
41    pub fn cross(self, other: Self) -> i64 {
42        self.x * other.y - self.y * other.x
43    }
44    /// 直交するベクトルを返す
45    pub fn normal(self) -> Self {
46        Self::new(-self.y, self.x)
47    }
48    /// ベクトルのなす角度を返す
49    pub fn angle(self, other: Self) -> f64 {
50        ((other.y - self.y) as f64).atan2((other.x - self.x) as f64)
51    }
52    /// `self`から`other`への角度($-\pi \le \theta \le \pi$)を返す。
53    pub fn angle_diff(self, other: Self) -> f64 {
54        let r = (other.y as f64).atan2(other.x as f64) - (self.y as f64).atan2(self.x as f64);
55
56        if r < -PI {
57            r + PI * 2.0
58        } else if r > PI {
59            r - PI * 2.0
60        } else {
61            r
62        }
63    }
64}
65
66impl_ops!(Add for VectorInt, |a: Self, b: Self| Self::new(a.x + b.x, a.y + b.y));
67impl_ops!(Sub for VectorInt, |a: Self, b: Self| Self::new(a.x - b.x, a.y - b.y));
68impl_ops!(Mul<i64> for VectorInt, |a: Self, k: i64| Self::new(a.x * k, a.y * k));
69impl_ops!(Div<i64> for VectorInt, |a: Self, k: i64| Self::new(a.x / k, a.y / k));
70
71impl_from!((i64, i64) => VectorInt, |value: (_, _)| Self::new(value.0, value.1));
72impl_from!(VectorInt => (i64, i64), |value: VectorInt| (value.x, value.y));