pub fn dijkstra_map<C: Cell>(
grid: &Grid<C>,
goals: &[(usize, usize)],
constraints: &PathfindingConstraints,
) -> DijkstraMapExpand description
Generate Dijkstra map from multiple goals
Examples found in repository?
examples/advanced_pathfinding.rs (line 26)
11fn main() {
12 println!("=== Advanced Pathfinding Demo ===\n");
13
14 // Generate a dungeon layout
15 let mut grid = Grid::new(25, 20);
16 let algo = algorithms::get("bsp").unwrap();
17 algo.generate(&mut grid, 54321);
18
19 println!("1. Dungeon Layout (25x20):");
20 print_grid(&grid);
21
22 // Single goal pathfinding
23 println!("\n2. Single Goal Dijkstra Map:");
24 let goals = vec![(12, 10)]; // Center goal
25 let constraints = PathfindingConstraints::default();
26 let dijkstra = dijkstra_map(&grid, &goals, &constraints);
27 print_dijkstra_map(&dijkstra);
28
29 // Multiple goals pathfinding
30 println!("\n3. Multiple Goals Dijkstra Map:");
31 let goals = vec![(5, 5), (20, 15), (15, 5)]; // Three goals
32 let dijkstra_multi = dijkstra_map(&grid, &goals, &constraints);
33 print_dijkstra_map(&dijkstra_multi);
34
35 // Flow field generation
36 println!("\n4. Flow Field from Single Goal:");
37 let flow = flow_field_from_dijkstra(&dijkstra);
38 print_flow_field(&flow);
39
40 // Custom movement costs
41 println!("\n5. Custom Movement Costs (diagonal penalty):");
42 let mut custom_constraints = PathfindingConstraints::default();
43 custom_constraints.movement_cost.insert((-1, -1), 2.0);
44 custom_constraints.movement_cost.insert((-1, 1), 2.0);
45 custom_constraints.movement_cost.insert((1, -1), 2.0);
46 custom_constraints.movement_cost.insert((1, 1), 2.0);
47
48 let dijkstra_custom = dijkstra_map(&grid, &goals, &custom_constraints);
49 print_dijkstra_map(&dijkstra_custom);
50
51 // Performance analysis
52 println!("\n6. Performance Analysis:");
53 let start = std::time::Instant::now();
54 let _ = dijkstra_map(&grid, &goals, &constraints);
55 println!(" Dijkstra map generation: {:?}", start.elapsed());
56
57 let start = std::time::Instant::now();
58 let _ = flow_field_from_dijkstra(&dijkstra);
59 println!(" Flow field generation: {:?}", start.elapsed());
60}More examples
examples/spatial_workflow.rs (line 76)
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}