pub struct StructuringElement { /* private fields */ }Expand description
Structuring element for morphological operations
Implementations§
Source§impl StructuringElement
impl StructuringElement
Sourcepub fn rectangle(width: usize, height: usize) -> Self
pub fn rectangle(width: usize, height: usize) -> Self
Create rectangular structuring element
Examples found in repository?
examples/morphological_operations.rs (line 24)
11fn main() {
12 println!("=== Morphological Operations Demo ===\n");
13
14 // Generate a cellular automata cave
15 let mut grid = Grid::new(30, 20);
16 let algo = algorithms::get("cellular").unwrap();
17 algo.generate(&mut grid, 98765);
18
19 println!("1. Original Cave System (30x20):");
20 print_grid(&grid);
21
22 // Erosion - shrink shapes
23 println!("\n2. Erosion (3x3 rectangle):");
24 let rect_element = StructuringElement::rectangle(3, 3);
25 let eroded = morphological_transform(&grid, MorphologyOp::Erosion, &rect_element);
26 print_grid(&eroded);
27
28 // Dilation - expand shapes
29 println!("\n3. Dilation (3x3 rectangle):");
30 let dilated = morphological_transform(&grid, MorphologyOp::Dilation, &rect_element);
31 print_grid(&dilated);
32
33 // Opening - erosion followed by dilation (removes small features)
34 println!("\n4. Opening (removes small features):");
35 let opened = morphological_transform(&grid, MorphologyOp::Opening, &rect_element);
36 print_grid(&opened);
37
38 // Closing - dilation followed by erosion (fills small gaps)
39 println!("\n5. Closing (fills small gaps):");
40 let closed = morphological_transform(&grid, MorphologyOp::Closing, &rect_element);
41 print_grid(&closed);
42
43 // Different structuring elements
44 println!("\n6. Circular Structuring Element (radius 2):");
45 let circle_element = StructuringElement::circle(2);
46 let circle_eroded = morphological_transform(&grid, MorphologyOp::Erosion, &circle_element);
47 print_grid(&circle_eroded);
48
49 println!("\n7. Cross Structuring Element (size 5):");
50 let cross_element = StructuringElement::cross(5);
51 let cross_dilated = morphological_transform(&grid, MorphologyOp::Dilation, &cross_element);
52 print_grid(&cross_dilated);
53
54 // Iterative processing
55 println!("\n8. Multiple Iterations (3x erosion):");
56 let mut iterative = grid.clone();
57 for i in 1..=3 {
58 iterative = morphological_transform(&iterative, MorphologyOp::Erosion, &rect_element);
59 println!(" Iteration {}:", i);
60 print_grid_compact(&iterative);
61 }
62
63 // Performance comparison
64 println!("\n9. Performance Analysis:");
65 let elements = [
66 ("Rectangle 3x3", StructuringElement::rectangle(3, 3)),
67 ("Circle r=2", StructuringElement::circle(2)),
68 ("Cross 5x5", StructuringElement::cross(5)),
69 ];
70
71 for (name, element) in &elements {
72 let start = std::time::Instant::now();
73 let _ = morphological_transform(&grid, MorphologyOp::Erosion, element);
74 println!(" {} erosion: {:?}", name, start.elapsed());
75 }
76
77 // Shape analysis
78 println!("\n10. Shape Analysis:");
79 let original_floors = grid.count(|t| t.is_floor());
80 let eroded_floors = eroded.count(|t| t.is_floor());
81 let dilated_floors = dilated.count(|t| t.is_floor());
82
83 println!(" Original floors: {}", original_floors);
84 println!(
85 " After erosion: {} ({:.1}% reduction)",
86 eroded_floors,
87 100.0 * (original_floors - eroded_floors) as f32 / original_floors as f32
88 );
89 println!(
90 " After dilation: {} ({:.1}% increase)",
91 dilated_floors,
92 100.0 * (dilated_floors - original_floors) as f32 / original_floors as f32
93 );
94}More examples
examples/spatial_workflow.rs (line 33)
14fn main() {
15 println!("=== Complete Spatial Analysis Workflow ===\n");
16
17 // Step 1: Generate base dungeon
18 println!("1. Generating Base Dungeon:");
19 let mut grid = Grid::new(40, 30);
20 let algo = algorithms::get("bsp").unwrap();
21 algo.generate(&mut grid, 42424);
22
23 let original_floors = grid.count(|t| t.is_floor());
24 println!(
25 " Generated {}x{} dungeon with {} floor tiles",
26 grid.width(),
27 grid.height(),
28 original_floors
29 );
30
31 // Step 2: Clean up with morphological operations
32 println!("\n2. Cleaning Up Small Features:");
33 let cleanup_element = StructuringElement::rectangle(3, 3);
34 let cleaned = morphological_transform(&grid, MorphologyOp::Opening, &cleanup_element);
35
36 let cleaned_floors = cleaned.count(|t| t.is_floor());
37 println!(
38 " Removed {} small features ({} floors remaining)",
39 original_floors - cleaned_floors,
40 cleaned_floors
41 );
42
43 // Step 3: Analyze distances from walls
44 println!("\n3. Analyzing Distance from Walls:");
45 let distance_map = distance_field(&cleaned, DistanceMetric::Euclidean);
46
47 let mut max_distance = 0.0;
48 let mut center_points = Vec::new();
49
50 for y in 0..distance_map.height() {
51 for x in 0..distance_map.width() {
52 let dist = distance_map.get(x, y);
53 if dist != f32::INFINITY {
54 if dist > max_distance {
55 max_distance = dist;
56 center_points.clear();
57 center_points.push((x, y));
58 } else if (dist - max_distance).abs() < 0.1 {
59 center_points.push((x, y));
60 }
61 }
62 }
63 }
64
65 println!(" Maximum distance from walls: {:.1}", max_distance);
66 println!(" Found {} center points", center_points.len());
67
68 // Step 4: Create strategic pathfinding network
69 println!("\n4. Creating Strategic Pathfinding Network:");
70
71 // Use the most central points as strategic locations
72 let strategic_points: Vec<_> = center_points.into_iter().take(3).collect();
73 println!(" Strategic points: {:?}", strategic_points);
74
75 let constraints = PathfindingConstraints::default();
76 let strategic_dijkstra = dijkstra_map(&cleaned, &strategic_points, &constraints);
77
78 // Step 5: Generate AI movement flow field
79 println!("\n5. Generating AI Movement Flow Field:");
80 let flow_field = flow_field_from_dijkstra(&strategic_dijkstra);
81
82 // Analyze flow field coverage
83 let mut flow_coverage = 0;
84 for y in 0..flow_field.height() {
85 for x in 0..flow_field.width() {
86 let (dx, dy) = flow_field.get_direction(x, y);
87 if dx != 0 || dy != 0 {
88 flow_coverage += 1;
89 }
90 }
91 }
92
93 println!(" Flow field covers {} cells", flow_coverage);
94
95 // Step 6: Identify chokepoints using morphological analysis
96 println!("\n6. Identifying Chokepoints:");
97 let thin_element = StructuringElement::rectangle(2, 2);
98 let thinned = morphological_transform(&cleaned, MorphologyOp::Erosion, &thin_element);
99
100 let mut chokepoints = Vec::new();
101 for y in 1..cleaned.height() - 1 {
102 for x in 1..cleaned.width() - 1 {
103 if let (Some(original), Some(thinned_cell)) = (
104 cleaned.get(x as i32, y as i32),
105 thinned.get(x as i32, y as i32),
106 ) {
107 if original.is_floor() && !thinned_cell.is_floor() {
108 // This was a floor that got eroded - potential chokepoint
109 let neighbors = count_floor_neighbors(&cleaned, x, y);
110 if (2..=4).contains(&neighbors) {
111 chokepoints.push((x, y));
112 }
113 }
114 }
115 }
116 }
117
118 println!(" Found {} potential chokepoints", chokepoints.len());
119
120 // Step 7: Performance summary
121 println!("\n7. Performance Summary:");
122
123 let start = std::time::Instant::now();
124 let _ = morphological_transform(&grid, MorphologyOp::Opening, &cleanup_element);
125 println!(" Morphological cleanup: {:?}", start.elapsed());
126
127 let start = std::time::Instant::now();
128 let _ = distance_field(&cleaned, DistanceMetric::Euclidean);
129 println!(" Distance field calculation: {:?}", start.elapsed());
130
131 let start = std::time::Instant::now();
132 let _ = dijkstra_map(&cleaned, &strategic_points, &constraints);
133 println!(" Dijkstra map generation: {:?}", start.elapsed());
134
135 let start = std::time::Instant::now();
136 let _ = flow_field_from_dijkstra(&strategic_dijkstra);
137 println!(" Flow field generation: {:?}", start.elapsed());
138
139 // Step 8: Spatial analysis results
140 println!("\n8. Spatial Analysis Results:");
141 println!(" Original dungeon: {} floors", original_floors);
142 println!(" After cleanup: {} floors", cleaned_floors);
143 println!(" Strategic locations: {}", strategic_points.len());
144 println!(" Chokepoints identified: {}", chokepoints.len());
145 println!(
146 " Flow field coverage: {:.1}%",
147 100.0 * flow_coverage as f32 / cleaned_floors as f32
148 );
149
150 println!("\n✅ Spatial analysis workflow complete!");
151 println!(" The dungeon is now ready for:");
152 println!(" - AI pathfinding using flow fields");
153 println!(" - Strategic placement at center points");
154 println!(" - Tactical analysis of chokepoints");
155 println!(" - Distance-based gameplay mechanics");
156}Sourcepub fn circle(radius: usize) -> Self
pub fn circle(radius: usize) -> Self
Create circular structuring element
Examples found in repository?
examples/morphological_operations.rs (line 45)
11fn main() {
12 println!("=== Morphological Operations Demo ===\n");
13
14 // Generate a cellular automata cave
15 let mut grid = Grid::new(30, 20);
16 let algo = algorithms::get("cellular").unwrap();
17 algo.generate(&mut grid, 98765);
18
19 println!("1. Original Cave System (30x20):");
20 print_grid(&grid);
21
22 // Erosion - shrink shapes
23 println!("\n2. Erosion (3x3 rectangle):");
24 let rect_element = StructuringElement::rectangle(3, 3);
25 let eroded = morphological_transform(&grid, MorphologyOp::Erosion, &rect_element);
26 print_grid(&eroded);
27
28 // Dilation - expand shapes
29 println!("\n3. Dilation (3x3 rectangle):");
30 let dilated = morphological_transform(&grid, MorphologyOp::Dilation, &rect_element);
31 print_grid(&dilated);
32
33 // Opening - erosion followed by dilation (removes small features)
34 println!("\n4. Opening (removes small features):");
35 let opened = morphological_transform(&grid, MorphologyOp::Opening, &rect_element);
36 print_grid(&opened);
37
38 // Closing - dilation followed by erosion (fills small gaps)
39 println!("\n5. Closing (fills small gaps):");
40 let closed = morphological_transform(&grid, MorphologyOp::Closing, &rect_element);
41 print_grid(&closed);
42
43 // Different structuring elements
44 println!("\n6. Circular Structuring Element (radius 2):");
45 let circle_element = StructuringElement::circle(2);
46 let circle_eroded = morphological_transform(&grid, MorphologyOp::Erosion, &circle_element);
47 print_grid(&circle_eroded);
48
49 println!("\n7. Cross Structuring Element (size 5):");
50 let cross_element = StructuringElement::cross(5);
51 let cross_dilated = morphological_transform(&grid, MorphologyOp::Dilation, &cross_element);
52 print_grid(&cross_dilated);
53
54 // Iterative processing
55 println!("\n8. Multiple Iterations (3x erosion):");
56 let mut iterative = grid.clone();
57 for i in 1..=3 {
58 iterative = morphological_transform(&iterative, MorphologyOp::Erosion, &rect_element);
59 println!(" Iteration {}:", i);
60 print_grid_compact(&iterative);
61 }
62
63 // Performance comparison
64 println!("\n9. Performance Analysis:");
65 let elements = [
66 ("Rectangle 3x3", StructuringElement::rectangle(3, 3)),
67 ("Circle r=2", StructuringElement::circle(2)),
68 ("Cross 5x5", StructuringElement::cross(5)),
69 ];
70
71 for (name, element) in &elements {
72 let start = std::time::Instant::now();
73 let _ = morphological_transform(&grid, MorphologyOp::Erosion, element);
74 println!(" {} erosion: {:?}", name, start.elapsed());
75 }
76
77 // Shape analysis
78 println!("\n10. Shape Analysis:");
79 let original_floors = grid.count(|t| t.is_floor());
80 let eroded_floors = eroded.count(|t| t.is_floor());
81 let dilated_floors = dilated.count(|t| t.is_floor());
82
83 println!(" Original floors: {}", original_floors);
84 println!(
85 " After erosion: {} ({:.1}% reduction)",
86 eroded_floors,
87 100.0 * (original_floors - eroded_floors) as f32 / original_floors as f32
88 );
89 println!(
90 " After dilation: {} ({:.1}% increase)",
91 dilated_floors,
92 100.0 * (dilated_floors - original_floors) as f32 / original_floors as f32
93 );
94}Sourcepub fn cross(size: usize) -> Self
pub fn cross(size: usize) -> Self
Create cross-shaped structuring element
Examples found in repository?
examples/morphological_operations.rs (line 50)
11fn main() {
12 println!("=== Morphological Operations Demo ===\n");
13
14 // Generate a cellular automata cave
15 let mut grid = Grid::new(30, 20);
16 let algo = algorithms::get("cellular").unwrap();
17 algo.generate(&mut grid, 98765);
18
19 println!("1. Original Cave System (30x20):");
20 print_grid(&grid);
21
22 // Erosion - shrink shapes
23 println!("\n2. Erosion (3x3 rectangle):");
24 let rect_element = StructuringElement::rectangle(3, 3);
25 let eroded = morphological_transform(&grid, MorphologyOp::Erosion, &rect_element);
26 print_grid(&eroded);
27
28 // Dilation - expand shapes
29 println!("\n3. Dilation (3x3 rectangle):");
30 let dilated = morphological_transform(&grid, MorphologyOp::Dilation, &rect_element);
31 print_grid(&dilated);
32
33 // Opening - erosion followed by dilation (removes small features)
34 println!("\n4. Opening (removes small features):");
35 let opened = morphological_transform(&grid, MorphologyOp::Opening, &rect_element);
36 print_grid(&opened);
37
38 // Closing - dilation followed by erosion (fills small gaps)
39 println!("\n5. Closing (fills small gaps):");
40 let closed = morphological_transform(&grid, MorphologyOp::Closing, &rect_element);
41 print_grid(&closed);
42
43 // Different structuring elements
44 println!("\n6. Circular Structuring Element (radius 2):");
45 let circle_element = StructuringElement::circle(2);
46 let circle_eroded = morphological_transform(&grid, MorphologyOp::Erosion, &circle_element);
47 print_grid(&circle_eroded);
48
49 println!("\n7. Cross Structuring Element (size 5):");
50 let cross_element = StructuringElement::cross(5);
51 let cross_dilated = morphological_transform(&grid, MorphologyOp::Dilation, &cross_element);
52 print_grid(&cross_dilated);
53
54 // Iterative processing
55 println!("\n8. Multiple Iterations (3x erosion):");
56 let mut iterative = grid.clone();
57 for i in 1..=3 {
58 iterative = morphological_transform(&iterative, MorphologyOp::Erosion, &rect_element);
59 println!(" Iteration {}:", i);
60 print_grid_compact(&iterative);
61 }
62
63 // Performance comparison
64 println!("\n9. Performance Analysis:");
65 let elements = [
66 ("Rectangle 3x3", StructuringElement::rectangle(3, 3)),
67 ("Circle r=2", StructuringElement::circle(2)),
68 ("Cross 5x5", StructuringElement::cross(5)),
69 ];
70
71 for (name, element) in &elements {
72 let start = std::time::Instant::now();
73 let _ = morphological_transform(&grid, MorphologyOp::Erosion, element);
74 println!(" {} erosion: {:?}", name, start.elapsed());
75 }
76
77 // Shape analysis
78 println!("\n10. Shape Analysis:");
79 let original_floors = grid.count(|t| t.is_floor());
80 let eroded_floors = eroded.count(|t| t.is_floor());
81 let dilated_floors = dilated.count(|t| t.is_floor());
82
83 println!(" Original floors: {}", original_floors);
84 println!(
85 " After erosion: {} ({:.1}% reduction)",
86 eroded_floors,
87 100.0 * (original_floors - eroded_floors) as f32 / original_floors as f32
88 );
89 println!(
90 " After dilation: {} ({:.1}% increase)",
91 dilated_floors,
92 100.0 * (dilated_floors - original_floors) as f32 / original_floors as f32
93 );
94}pub fn width(&self) -> usize
pub fn height(&self) -> usize
pub fn get(&self, x: usize, y: usize) -> bool
Trait Implementations§
Source§impl Clone for StructuringElement
impl Clone for StructuringElement
Source§fn clone(&self) -> StructuringElement
fn clone(&self) -> StructuringElement
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreAuto Trait Implementations§
impl Freeze for StructuringElement
impl RefUnwindSafe for StructuringElement
impl Send for StructuringElement
impl Sync for StructuringElement
impl Unpin for StructuringElement
impl UnwindSafe for StructuringElement
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more