1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate::prelude::*;
use std::collections::HashMap;
pub struct Cluster<HB>
where
HB: HasBoundingBox3D,
{
data: Vec<HB>,
map: HashMap<(u16, u16), Vec<usize>>,
start_x: f64,
start_y: f64,
incr_x: f64,
incr_y: f64,
}
impl<HB> Cluster<HB>
where
HB: HasBoundingBox3D,
{
pub fn new(data: Vec<HB>, count_x: u16, count_y: u16) -> Result<Self> {
let mut map: HashMap<(u16, u16), Vec<usize>> = HashMap::new();
let mut bb_all: Result<BoundingBox3D> = Err(ErrorKind::BoundingBoxMissing);
for x in data.iter() {
let bb = x.bounding_box();
if let Ok(all) = bb_all {
bb_all = Ok(all.combine(&&bb));
} else {
bb_all = Ok(bb);
}
}
let bb = bb_all?;
let (start_x, start_y) = (bb.min_p().x(), bb.min_p().y());
let (size_x, size_y) = (bb.size_x().get(), bb.size_y().get());
let (incr_x, incr_y) = (size_x / count_x as f64, size_y / count_y as f64);
for (i, x) in data.iter().enumerate() {
let xbb = x.bounding_box();
let (min_x, min_y) = (xbb.min_p().x(), xbb.min_p().y());
let (max_x, max_y) = (xbb.max_p().x(), xbb.max_p().y());
let c_min_x = ((min_x - start_x) / incr_x) as u16;
let c_min_y = ((min_y - start_y) / incr_y) as u16;
let c_max_x = ((max_x - start_x) / incr_x) as u16;
let c_max_y = ((max_y - start_y) / incr_y) as u16;
for cx in c_min_x..=c_max_x {
for cy in c_min_y..=c_max_y {
map.entry((cx, cy))
.and_modify(|e| e.push(i))
.or_insert(vec![i]);
}
}
}
Ok(Self {
data,
map,
start_x,
start_y,
incr_x,
incr_y,
})
}
pub fn for_each_candidate<'a>(&'a self, x: f64, y: f64, f: &mut dyn FnMut(&HB)) {
let c_x = ((x - self.start_x) / self.incr_x) as u16;
let c_y = ((y - self.start_y) / self.incr_y) as u16;
if let Some(is) = self.map.get(&(c_x, c_y)) {
for i in is {
f(&self.data[*i]);
}
}
}
}