haar_lib/geom_int/
closest_pair.rs1use crate::chmin;
7use crate::{algo::merge::*, geom_int::*};
8
9pub fn closest_pair(ps: Vec<VectorInt>) -> Option<((usize, VectorInt), (usize, VectorInt))> {
11 if ps.len() < 2 {
12 None
13 } else {
14 let mut ps: Vec<_> = ps.into_iter().enumerate().collect();
15 ps.sort_by(|(_, p), (_, q)| p.x.cmp(&q.x));
16 rec(&mut ps)
17 }
18}
19
20fn rec(ps: &mut [(usize, VectorInt)]) -> Option<((usize, VectorInt), (usize, VectorInt))> {
21 let n = ps.len();
22 match n {
23 0 => unreachable!(),
24 1 => None,
25 2 => {
26 if ps[0].1.y > ps[1].1.y {
27 ps.swap(0, 1);
28 }
29 Some((ps[0], ps[1]))
30 }
31 _ => {
32 let mid_x = ps[n / 2].1.x;
33 let (left, right) = ps.split_at_mut(n / 2);
34 let d1 = rec(left);
35 let d2 = rec(right);
36
37 inplace_merge_by(ps, n / 2, |a, b| a.1.y < b.1.y);
38
39 let mut d = i64::MAX;
40 let mut ret = None;
41
42 if let Some((p, q)) = d1 {
43 let t = (p.1 - q.1).abs_sq();
44 if chmin!(d, t) {
45 ret = Some((p, q));
46 }
47 }
48 if let Some((p, q)) = d2 {
49 let t = (p.1 - q.1).abs_sq();
50 if chmin!(d, t) {
51 ret = Some((p, q));
52 }
53 }
54
55 let mut v: Vec<(usize, VectorInt)> = vec![];
56
57 for &mut p in ps {
58 let t = (p.1.x - mid_x).abs();
59 if t * t >= d {
60 continue;
61 }
62
63 for &q in v.iter().rev() {
64 let t = (p.1.y - q.1.y).abs();
65 if t * t >= d {
66 break;
67 }
68
69 let t = (p.1 - q.1).abs_sq();
70 if chmin!(d, t) {
71 ret = Some((p, q));
72 }
73 }
74
75 v.push(p);
76 }
77
78 ret
79 }
80 }
81}