Mapping Radio Shadows with Flood Fill
Your quadcopter hovers at 200 metres, its RF analyzer detecting a curious phenomenon: a complete signal shadow behind a cell tower. One sample point shows dead air, but where does this shadow end? Traditional approaches might probe every adjacent point methodically, but that’s flying time you don’t have.
Enter flood fill—the algorithm that’s been painting computer screens since the early graphics terminals. Originally designed to fill enclosed areas with colour, it’s perfect for mapping connected regions of radio silence.
func floodFill(_ grid: inout [[Int]], _ row: Int, _ col: Int, _ newVal: Int, _ origVal: Int) {
if row < 0 || row >= grid.count || col < 0 || col >= grid[0].count { return }
if grid[row][col] != origVal || grid[row][col] == newVal { return }
grid[row][col] = newVal
floodFill(&grid, row + 1, col, newVal, origVal)
floodFill(&grid, row - 1, col, newVal, origVal)
floodFill(&grid, row, col + 1, newVal, origVal)
floodFill(&grid, row, col - 1, newVal, origVal)
}
Swift’s clean recursion handles the four-directional spread elegantly, but that call stack builds up fast over large shadow zones. Perl takes a different approach:
sub flood_fill {
my ($grid, $row, $col, $new_val, $orig_val) = @_;
my @stack = ([$row, $col]);
while (@stack) {
my ($r, $c) = @{pop @stack};
next if $r < 0 || $r >= @$grid || $c < 0 || $c >= @{$grid->[0]};
next if $grid->[$r][$c] != $orig_val || $grid->[$r][$c] == $new_val;
$grid->[$r][$c] = $new_val;
push @stack, [$r+1, $c], [$r-1, $c], [$r, $c+1], [$r, $c-1];
}
}
Perl’s iterative stack prevents overflow while maintaining the same spreading pattern. Both approaches turn one dead signal reading into a complete shadow map, transforming scattered data points into contiguous regions your navigation system can actually use.
The beauty lies in the simplicity: one algorithm, born from graphics programming, now mapping invisible electromagnetic landscapes from the sky.