-
Notifications
You must be signed in to change notification settings - Fork 185
/
concavehull-usage.rs
84 lines (77 loc) · 2.9 KB
/
concavehull-usage.rs
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
use geo::ConcaveHull;
use geo::ConvexHull;
use geo::{Coordinate, Point};
use geo_types::MultiPoint;
use std::fs::File;
use std::io::Write;
fn generate_polygon_str(coords: &[Coordinate]) -> String {
let mut points_str = String::from("");
for coord in coords {
points_str.push_str(format!("{},{} ", coord.x, coord.y).as_ref());
}
format!(
" <polygon points=\"{}\" fill=\"none\" stroke=\"black\"/>\n",
points_str
)
}
fn generate_consecutive_circles(coords: &[Coordinate]) -> String {
let mut circles_str = String::from("");
for coord in coords {
circles_str.push_str(
format!("<circle cx=\"{}\" cy=\"{}\" r=\"1\"/>\n", coord.x, coord.y).as_ref(),
);
}
circles_str
}
fn produce_file_content(start_str: &str, mid_str: &str) -> String {
let mut overall_string = start_str.to_string();
overall_string.push_str(mid_str);
overall_string.push_str("</svg>");
overall_string
}
//Move the points such that they're clustered around the center of the image
fn move_points_in_viewbox(width: f64, height: f64, points: Vec<Point>) -> Vec<Point> {
let mut new_points = vec![];
for point in points {
new_points.push(Point::new(
point.0.x + width / 2.0,
point.0.y + height / 2.0,
));
}
new_points
}
fn map_points_to_coords(points: Vec<Point>) -> Vec<Coordinate> {
points.iter().map(|point| point.0).collect()
}
fn main() -> std::io::Result<()> {
let mut points_file = File::create("points.svg")?;
let mut concave_hull_file = File::create("concavehull.svg")?;
let mut convex_hull_file = File::create("convexhull.svg")?;
let width = 100;
let height = 100;
let svg_file_string = format!(
"<svg viewBox=\"50 50 {} {}\" xmlns=\"http://www.w3.org/2000/svg\">\n",
width, height
);
let norway = geo_test_fixtures::norway_main::<f64>();
let v: Vec<_> = norway
.0
.into_iter()
.map(|coord| Point::new(coord.x, coord.y))
.collect();
let moved_v = move_points_in_viewbox(width as f64, height as f64, v);
let multipoint = MultiPoint::from(moved_v);
let concave = multipoint.concave_hull(2.0);
let convex = multipoint.convex_hull();
let concave_polygon_str = generate_polygon_str(&concave.exterior().0);
let convex_polygon_str = generate_polygon_str(&convex.exterior().0);
let v_coords = map_points_to_coords(multipoint.0);
let circles_str = generate_consecutive_circles(&v_coords);
let points_str = produce_file_content(&svg_file_string, &circles_str);
let concave_hull_str = produce_file_content(&svg_file_string, &concave_polygon_str);
let convex_hull_str = produce_file_content(&svg_file_string, &convex_polygon_str);
points_file.write_all(points_str.as_ref())?;
concave_hull_file.write_all(concave_hull_str.as_ref())?;
convex_hull_file.write_all(convex_hull_str.as_ref())?;
Ok(())
}