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
107
108
109
110
111
112
113
114
115
116
117
118
use super::ray_cast::*;
use super::super::path::*;
use super::super::graph_path::*;
use super::super::super::super::geo::*;
impl<Point: Coordinate+Coordinate2D> GraphPath<Point, PathLabel> {
pub fn set_exterior_by_adding(&mut self) {
self.set_edge_kinds_by_ray_casting(|path_crossings| (path_crossings[0]&1) != 0 || (path_crossings[1]&1) != 0);
}
pub fn set_exterior_by_removing_interior_points(&mut self) {
self.set_edge_kinds_by_ray_casting(|path_crossings| path_crossings[0] != 0 || path_crossings[1] != 0);
}
}
pub fn path_add<P1: BezierPath, P2: BezierPath, POut: BezierPathFactory>(path1: &Vec<P1>, path2: &Vec<P2>, accuracy: f64) -> Vec<POut>
where P1::Point: Coordinate+Coordinate2D,
P2: BezierPath<Point=P1::Point>,
POut: BezierPathFactory<Point=P1::Point> {
if path1.len() == 0 {
return path2.iter()
.map(|path| POut::from_path(path))
.collect();
} else if path2.len() == 0 {
return path1.iter()
.map(|path| POut::from_path(path))
.collect();
}
let mut merged_path = GraphPath::new();
merged_path = merged_path.merge(GraphPath::from_merged_paths(path1.into_iter().map(|path| (path, PathLabel(0, PathDirection::from(path))))));
merged_path = merged_path.collide(GraphPath::from_merged_paths(path2.into_iter().map(|path| (path, PathLabel(1, PathDirection::from(path))))), accuracy);
merged_path.round(accuracy);
merged_path.set_exterior_by_adding();
merged_path.heal_exterior_gaps();
merged_path.exterior_paths()
}
pub fn path_remove_interior_points<P1: BezierPath, POut: BezierPathFactory>(path: &Vec<P1>, accuracy: f64) -> Vec<POut>
where P1::Point: Coordinate+Coordinate2D,
POut: BezierPathFactory<Point=P1::Point> {
let mut merged_path = GraphPath::new();
merged_path = merged_path.merge(GraphPath::from_merged_paths(path.into_iter().map(|path| (path, PathLabel(0, PathDirection::from(path))))));
merged_path.self_collide(accuracy);
merged_path.round(accuracy);
merged_path.set_exterior_by_removing_interior_points();
merged_path.heal_exterior_gaps();
let result = merged_path.exterior_paths();
test_assert!(result.len() != 0 || path.len() == 0);
result
}
pub fn path_remove_overlapped_points<P1: BezierPath, POut: BezierPathFactory>(path: &Vec<P1>, accuracy: f64) -> Vec<POut>
where P1::Point: Coordinate+Coordinate2D,
POut: BezierPathFactory<Point=P1::Point> {
let mut merged_path = GraphPath::new();
merged_path = merged_path.merge(GraphPath::from_merged_paths(path.into_iter().map(|path| (path, PathLabel(0, PathDirection::from(path))))));
merged_path.self_collide(accuracy);
merged_path.round(accuracy);
merged_path.set_exterior_by_adding();
merged_path.heal_exterior_gaps();
let result = merged_path.exterior_paths();
test_assert!(result.len() != 0 || path.len() == 0);
result
}