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
use point_cloud_2d::*;
use traits::is_2d::*;
use traits::is_buildable_2d::*;
use traits::is_sortable_2d::*;
use traits::is_random_accessible::*;
pub fn convex_hull_2d<RA, P>(ra: &RA) -> Vec<P> where
RA: IsRandomAccessible<P>,
P: Is2D + IsBuildable2D + Clone {
let n = ra.len();
let mut sorted = PointCloud2D::new();
sorted.append_ra(ra);
sorted.sort_x();
let sorted = sorted;
let mut lower = Vec::<P>::new();
for i in 0..n {
while lower.len() >= 2 && ccw(&lower[lower.len()-2], &lower[lower.len()-1], &sorted[i]) <= 0.0 {
println!("pop");
lower.pop().unwrap();
}
lower.push(sorted[i].clone());
}
let mut upper = Vec::<P>::new();
for i in (0..n).rev() {
while upper.len() >= 2 && ccw(&upper[upper.len()-2], &upper[upper.len()-1], &sorted[i]) <= 0.0 {
upper.pop().unwrap();
}
upper.push(sorted[i].clone());
}
if lower.len() > 0 { lower.pop().unwrap(); }
if upper.len() > 0 { upper.pop().unwrap(); }
let mut result = Vec::<P>::new();
result.extend(lower);
result.extend(upper);
result
}
fn ccw<P1, P2, P3>(p1: &P1, p2: &P2, p3: &P3) -> f64 where
P1: Is2D,
P2: Is2D,
P3: Is2D {
(p2.x() - p1.x())*(p3.y() - p1.y()) - (p2.y() - p1.y())*(p3.x() - p1.x())
}