polygon_offsetting/
draw_svg.rs1use crate::Offset;
2
3use std::path::Path;
4use std::fs::File;
5use std::io::Write;
6
7#[derive(Debug, Default)]
8pub struct Segm {
9 p1: (f64, f64),
10 p2: (f64, f64)
11}
12
13pub fn draw_svg_offset(
14 initial_contour: &Vec<(f64, f64)>,
15 offset: &Offset,
16 dir_path: &str,
17 filename: &str
18) -> Result <(), Box<dyn std::error::Error>> {
19 let mut segments: Vec<Segm> = Vec::new();
20 let mut segms: Vec<Segm> = Vec::new();
21
22 for i in 1..initial_contour.len() {
23 let mut sgmt: Segm = Segm::default();
24
25 sgmt.p1.0 = initial_contour[i - 1].0;
26 sgmt.p1.1 = initial_contour[i - 1].1;
27 if i == initial_contour.len() {
28 sgmt.p2.0 = initial_contour[0].0;
29 sgmt.p2.1 = initial_contour[0].1;
30 segms.push(sgmt);
31 break ;
32 }
33 sgmt.p2.0 = initial_contour[i].0;
34 sgmt.p2.1 = initial_contour[i].1;
35 segms.push(sgmt);
36 }
37
38 let contour_offset = offset.contour.clone();
39 for i in 1..contour_offset.len() {
40 let mut sgmt: Segm = Segm::default();
41
42 sgmt.p1.0 = contour_offset[i - 1].0;
43 sgmt.p1.1 = contour_offset[i - 1].1;
44 if i == contour_offset.len() {
45 sgmt.p2.0 = contour_offset[0].0;
46 sgmt.p2.1 = contour_offset[0].1;
47 segms.push(sgmt);
48 break ;
49 }
50 sgmt.p2.0 = contour_offset[i].0;
51 sgmt.p2.1 = contour_offset[i].1;
52 segms.push(sgmt);
53 }
54
55 segments.append(&mut segms);
56
57 let mut x_min1 = 0.;
58 let mut y_min1 = 0.;
59 for i in 0..segments.len() {
60 if i == 0 {
61 x_min1 = segments[i].p1.0;
62 y_min1 = segments[i].p1.1;
63 } else {
64 if segments[i].p1.0 < x_min1 { x_min1 = segments[i].p1.0; }
65 if segments[i].p2.0 < x_min1 { x_min1 = segments[i].p2.0; }
66 if segments[i].p1.1 < y_min1 { y_min1 = segments[i].p1.1; }
67 if segments[i].p2.1 < y_min1 { y_min1 = segments[i].p2.1; }
68 }
69 }
70 segments.iter_mut().for_each(|p| {
71 p.p1.0 -= x_min1;
72 p.p2.0 -= x_min1;
73 p.p1.1 -= y_min1;
74 p.p2.1 -= y_min1;
75
76 });
77
78 let mut max_x: f64 = std::f64::NEG_INFINITY;
79 let mut max_y: f64 = std::f64::NEG_INFINITY;
80 segments.iter().for_each(|segment| {
81 let p = &segment.p1;
82 if max_x < p.0 { max_x = p.0 }
83 if max_y < p.1 { max_x = p.1 }
84
85 let p = &segment.p2;
86 if max_x < p.0 { max_x = p.0 }
87 if max_y < p.1 { max_y = p.1 }
88 });
89
90 let resize_width = max_x / 1800.0;
91 let resize_height = max_y / 850.0;
92 let resize = if resize_width > resize_height { resize_width } else { resize_height };
93 segments.iter_mut().for_each(|s| {
94 s.p1.0 = s.p1.0 / resize;
95 s.p1.1 = s.p1.1 / resize;
96 s.p2.0 = s.p2.0 / resize;
97 s.p2.1 = s.p2.1 / resize;
98 });
99
100 let mut viewbox = vec![
101 std::f64::INFINITY,
102 std::f64::INFINITY,
103 std::f64::NEG_INFINITY,
104 std::f64::NEG_INFINITY
105 ];
106
107 segments.iter().for_each(|segment| {
108 let p = &segment.p1;
109 if viewbox[0] > p.0 { viewbox[0] = p.0 }
110 if viewbox[1] > p.1 { viewbox[1] = p.1 }
111 if viewbox[2] < p.0 { viewbox[2] = p.0 }
112 if viewbox[3] < p.1 { viewbox[3] = p.1 }
113
114 let p = &segment.p2;
115 if viewbox[0] > p.0 { viewbox[0] = p.0 }
116 if viewbox[1] > p.1 { viewbox[1] = p.1 }
117 if viewbox[2] < p.0 { viewbox[2] = p.0 }
118 if viewbox[3] < p.1 { viewbox[3] = p.1 }
119 });
120
121 let mut txt = format!(
122 "<?xml version='1.0' encoding='UTF-8' standalone='no'?>
123 <svg xmlns='http://www.w3.org/2000/svg' viewBox='{} {} {} {}' id='export' style='background-color:white'>\n",
124 viewbox[0] - 50., viewbox[1] - 50. , viewbox[2] + 100., viewbox[3] + 100. ).to_string();
125
126 let mut i: usize = 0;
127 segments.iter().for_each(|segment| {
128 let p1 = segment.p1;
129 let p2 = segment.p2;
130
131 let mut path = "M ".to_string();
132
133 path = format!("{} {} {} ", path, p1.0, (viewbox[3] - viewbox[1]) - (p1.1 - viewbox[1]));
134 path = format!("{} {} {} ", path, p2.0, (viewbox[3] - viewbox[1]) - (p2.1 - viewbox[1]));
135
136
137 let color = "#000000";
138 let width = 1.;
139
140 txt = format!("{}<path style='fill:none;stroke-width:{};stroke:{};' d='{}' id='{}' />\n", txt, width, color, path, 0);
141 i += 1;
142 });
143
144 txt = format!("{}</svg>", txt);
145 let env_path = std::env::current_dir().unwrap().to_str().unwrap().to_string();
146 let dir = env_path.clone() + &dir_path;
147
148 if !(Path::new(&dir_path).exists()) {
149 std::fs::create_dir_all(&dir)?;
150 }
151 let mut file = File::create(format!("{}.svg", dir.clone() + &filename)).map_err(|e| {
152 print!("Error on creating offset svg: {:?}", dir.clone() + &filename);
153 e
154 })?;
155 file.write_all(txt.as_bytes()).unwrap();
156
157 Ok(())
158}