MCPcopy Create free account
hub / github.com/ecto/muni / generate

Function generate

depot/dispatch/src/coverage.rs:44–178  ·  view source on GitHub ↗

Generate boustrophedon coverage waypoints for a polygon zone.

(polygon_wps: &[Waypoint], config: &CoverageConfig)

Source from the content-addressed store, hash-verified

42
43/// Generate boustrophedon coverage waypoints for a polygon zone.
44pub fn generate(polygon_wps: &[Waypoint], config: &CoverageConfig) -> Result<CoverageResult, String> {
45 if polygon_wps.len() < 3 {
46 return Err("Polygon must have at least 3 vertices".into());
47 }
48 if config.tool_width <= 0.0 {
49 return Err("Tool width must be positive".into());
50 }
51 if !(0.0..=50.0).contains(&config.overlap_pct) {
52 return Err("Overlap must be between 0 and 50 percent".into());
53 }
54
55 // Build geo polygon from waypoints
56 let coords: Vec<Coord> = polygon_wps.iter().map(|w| Coord { x: w.x, y: w.y }).collect();
57 let line_string = LineString::new(coords.clone());
58 let polygon = Polygon::new(line_string, vec![]);
59
60 // Determine sweep angle
61 let angle = config.swath_angle.unwrap_or_else(|| longest_edge_angle(&coords));
62
63 // Rotation transform: rotate polygon so sweep direction aligns with X axis
64 let cos_a = angle.cos();
65 let sin_a = angle.sin();
66 // Rotate by -angle to align sweep with X
67 let to_sweep = AffineTransform::new(cos_a, sin_a, 0.0, -sin_a, cos_a, 0.0);
68 // Inverse: rotate back by +angle
69 let from_sweep = AffineTransform::new(cos_a, -sin_a, 0.0, sin_a, cos_a, 0.0);
70
71 let rotated = polygon.affine_transform(&to_sweep);
72
73 let bbox = rotated
74 .bounding_rect()
75 .ok_or("Failed to compute bounding rectangle")?;
76
77 let step = config.tool_width * (1.0 - config.overlap_pct / 100.0);
78 if step <= 0.0 {
79 return Err("Effective step size must be positive".into());
80 }
81
82 let y_min = bbox.min().y;
83 let y_max = bbox.max().y;
84 let x_min = bbox.min().x;
85 let x_max = bbox.max().x;
86
87 // Small margin to extend sweep lines past polygon bounds
88 let x_margin = (x_max - x_min) * 0.01;
89
90 // Generate sweep lines and intersect with rotated polygon
91 let mut sweep_segments: Vec<Vec<(f64, f64)>> = Vec::new();
92 let mut y = y_min + step / 2.0;
93
94 while y <= y_max {
95 let sweep_line = Line::new(
96 Coord {
97 x: x_min - x_margin,
98 y,
99 },
100 Coord {
101 x: x_max + x_margin,

Callers 9

generate_coverageFunction · 0.85
rectangular_coverageFunction · 0.85
overlap_reduces_spacingFunction · 0.85
l_shaped_polygonFunction · 0.85
narrow_corridorFunction · 0.85
test_banana_generationFunction · 0.85
test_human_generationFunction · 0.85
mainFunction · 0.85

Calls 9

longest_edge_angleFunction · 0.85
intersect_line_polygonFunction · 0.85
compute_path_lengthFunction · 0.85
iterMethod · 0.80
partial_cmpMethod · 0.80
lenMethod · 0.45
containsMethod · 0.45
pushMethod · 0.45
is_emptyMethod · 0.45

Tested by 7

rectangular_coverageFunction · 0.68
overlap_reduces_spacingFunction · 0.68
l_shaped_polygonFunction · 0.68
narrow_corridorFunction · 0.68
test_banana_generationFunction · 0.68
test_human_generationFunction · 0.68