Skip to content

Flood fill chapter #738

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,7 @@
* [Split-Operator Method](contents/split-operator_method/split-operator_method.md)
* [Data Compression](contents/data_compression/data_compression.md)
* [Huffman Encoding](contents/huffman_encoding/huffman_encoding.md)
* [Computer Graphics](contents/computer_graphics/computer_graphics.md)
* [Flood Fill](contents/flood_fill/flood_fill.md)
* [Quantum Information](contents/quantum_information/quantum_information.md)
* [Computus](contents/computus/computus.md)
17 changes: 17 additions & 0 deletions contents/computer_graphics/computer_graphics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Computer Graphics

Of all areas of computer science research, none have had more of an immediate impact on multimedia than computer graphics.
This sub-field is distinctly different than computational science in that it focuses on the *appearance* of realistic details, instead of computing those details precisely.
Where a computational scientist might spend years writing software that runs on the fastest computers known to man to simulate climate, the computer graphics researcher might apply machine learning to create fluid simulations that look good enough to the untrained eye.
In the end, the computational scientist will have a plot and the computer graphics researcher will have a beautifully rendered simulation.

Though I may have painted computer graphics to be a bit hand-wavey, that could not be further from the truth!
Instead, I would argue that this field of research provides the closest approximation to realistic visualizations that desktop hardware can currently support.
Many art and video game studios are interested in telling a complete story via computational media, and this simply would not be possible without the rigorous efforts of researchers from around the world.
This is why Pixar hires researchers and will actively publish their findings after their movies are released.

Though the boundary between computer science research fields is a bit vague, for the purposes of the Algorithm Archive, we will broadly classify computer graphics as anything with direct applications to images or fields that can be represented as images.
Convolutions, for example, would not be considered part of computer graphics because they are used widely in all areas of computer science research; however, Canny edge detection will be.
We will also be covering a wide range of applications that are used for rendering high-resolution graphics and computational art.

As with all sections to the Algorithm Archive, this is a work in progress and subject to change, so feel free to let me know what you think!
153 changes: 153 additions & 0 deletions contents/flood_fill/code/julia/flood_fill.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
using DataStructures
using Test

# Function to check to make sure we are on the canvas
function inbounds(canvas_size, loc)

# Make sure we are not beneath or to the left of the canvas
if minimum(Tuple(loc)) < 1
return false

# Make sure we are not to the right of the canvas
elseif loc[2] > canvas_size[2]
return false

# Make sure we are not above the canvas
elseif loc[1] > canvas_size[1]
return false
else
return true
end
end

function color!(canvas, loc::CartesianIndex, old_val, new_val)
# bounds check, do not color if no in bounds!
if !inbounds(size(canvas), loc)
return
end

# Only change color if the element value is the old value
if (canvas[loc] != old_val)
return
else
canvas[loc] = new_val
end
end

function find_neighbors(canvas, loc::CartesianIndex, old_val, new_val)

# Finding north, south, east, west neighbors
possible_neighbors = [loc + CartesianIndex(0, 1),
loc + CartesianIndex(1, 0),
loc + CartesianIndex(0, -1),
loc + CartesianIndex(-1, 0)]

# Exclusing neighbors that should not be colored
neighbors = []
for possible_neighbor in possible_neighbors
if inbounds(size(canvas), possible_neighbor) &&
canvas[possible_neighbor] == old_val
push!(neighbors, possible_neighbor)
end
end

return neighbors
end

function stack_fill!(canvas, loc::CartesianIndex, old_val, new_val)
if new_val == old_val
return
end

s = Stack{CartesianIndex}()
push!(s, loc)

while length(s) > 0
current_loc = pop!(s)
if canvas[current_loc] == old_val
color!(canvas, current_loc, old_val, new_val)
possible_neighbors = find_neighbors(canvas, current_loc,
old_val, new_val)
for neighbor in possible_neighbors
push!(s,neighbor)
end
end

end
end


function queue_fill!(canvas, loc::CartesianIndex, old_val, new_val)
if new_val == old_val
return
end

q = Queue{CartesianIndex}()
enqueue!(q, loc)

# Coloring the initial location
color!(canvas, loc, old_val, new_val)

while length(q) > 0
current_loc = dequeue!(q)

possible_neighbors = find_neighbors(canvas, current_loc,
old_val, new_val)

# Coloring as we are enqueuing neighbors
for neighbor in possible_neighbors
color!(canvas, neighbor, old_val, new_val)
enqueue!(q,neighbor)
end

end
end

function recursive_fill!(canvas, loc::CartesianIndex, old_val, new_val)

if (old_val == new_val)
return
end

color!(canvas, loc, old_val, new_val)

possible_neighbors = find_neighbors(canvas, loc, old_val, new_val)
for possible_neighbor in possible_neighbors
recursive_fill!(canvas, possible_neighbor, old_val, new_val)
end
end

function main()

# Creation of a 5x5 grid with a single row of 1.0 elements
grid = zeros(5,5)
grid[3,:] .= 1

# Create solution grid
answer_grid = zeros(5,5)
answer_grid[1:3, :] .= 1

# Start filling at 1,1
start_loc = CartesianIndex(1,1)

@testset "Fill Methods" begin
# Use recursive method and reinitialize grid
recursive_fill!(grid, start_loc, 0.0, 1.0)
@test grid == answer_grid

grid[1:2,:] .= 0

# Use queue method and reinitialize grid
queue_fill!(grid, start_loc, 0.0, 1.0)
@test grid == answer_grid

grid[1:2,:] .= 0

# Use stack method and reinitialize grid
stack_fill!(grid, start_loc, 0.0, 1.0)
@test grid == answer_grid
end

end

main()
Loading