2019-05-11 08:51:24 +00:00
|
|
|
|
//
|
2019-05-18 18:53:32 +00:00
|
|
|
|
// This source code is property of the Computer Graphics and Visualization
|
|
|
|
|
// chair of the TU Dresden. Do not distribute in modified or unmodified form!
|
2019-05-11 08:51:24 +00:00
|
|
|
|
// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
|
|
|
|
|
//
|
|
|
|
|
#include "non_recursive_fill_tool.h"
|
|
|
|
|
#include <deque>
|
|
|
|
|
|
2019-05-18 18:53:32 +00:00
|
|
|
|
#include <iostream>
|
|
|
|
|
|
2019-05-11 08:51:24 +00:00
|
|
|
|
// Initialize the tool and store a reference of a canvas_buffer
|
2019-05-18 18:53:32 +00:00
|
|
|
|
non_recursive_fill_tool::non_recursive_fill_tool(canvas_buffer &canvas) : tool_base(canvas)
|
2019-05-11 08:51:24 +00:00
|
|
|
|
{
|
|
|
|
|
// This tool has no shape and is not draggable
|
|
|
|
|
shape = TS_NONE;
|
|
|
|
|
is_draggable = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A pixel to be put into the queue of pixels to process
|
2019-05-18 18:53:32 +00:00
|
|
|
|
struct waiting_pixel
|
|
|
|
|
{
|
|
|
|
|
waiting_pixel(int x, int y) : x(x), y(y) {}
|
|
|
|
|
waiting_pixel() : x(0), y(0) {}
|
2019-05-11 08:51:24 +00:00
|
|
|
|
|
2019-05-18 18:53:32 +00:00
|
|
|
|
int x, y;
|
|
|
|
|
};
|
2019-05-11 08:51:24 +00:00
|
|
|
|
|
2019-05-18 18:53:32 +00:00
|
|
|
|
void print_point(int x, int y)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "point (" << x << ", " << y << ")" << std::endl;
|
|
|
|
|
}
|
2019-05-11 08:51:24 +00:00
|
|
|
|
|
|
|
|
|
void non_recursive_fill_tool::draw(int x, int y)
|
|
|
|
|
{
|
|
|
|
|
waiting_pixel p;
|
2019-05-18 18:53:32 +00:00
|
|
|
|
std::deque<waiting_pixel> stack;
|
2019-05-11 08:51:24 +00:00
|
|
|
|
|
|
|
|
|
/************
|
|
|
|
|
Task 3.2.2. Implement a filling algothim without recursion. Use a stack instead.
|
2019-05-18 18:53:32 +00:00
|
|
|
|
The source code below inserts the first element into the stack and
|
2019-05-11 08:51:24 +00:00
|
|
|
|
starts a loop that reads the front element from the stack and removes
|
|
|
|
|
it. Your task is to fill the functionality in the loop. Before you begin
|
2019-05-18 18:53:32 +00:00
|
|
|
|
think about when to set the pixel (at the beginning of the loop or after
|
2019-05-11 08:51:24 +00:00
|
|
|
|
the stack was updated with neighbours). Use "canvas.set_pixel" to set
|
|
|
|
|
a pixel and "canvas.get_pixel" to read the state of a pixel.
|
2019-05-18 18:53:32 +00:00
|
|
|
|
Aufgabe 3.2.2. Implementieren Sie einen F<EFBFBD>llalgorithmus ohne Rekursion zu verwenden.
|
2019-05-11 08:51:24 +00:00
|
|
|
|
Nutzen Sie stattdessen einen Stack. Der vorgegebene Quelltext unten fuegt
|
2019-05-18 18:53:32 +00:00
|
|
|
|
das erste Element in den Stack ein und startet eine Schleife, die das
|
|
|
|
|
vorderste Element aus dem Stack liest und es anschlie<EFBFBD>end entfernt.
|
2019-05-11 08:51:24 +00:00
|
|
|
|
Ihre Aufgabe ist es die Funktionalitaet im Inneren der Schleife zu
|
|
|
|
|
ergaenzen. Bevor Sie beginnen machen Sie sich Gedanken an welcher Stelle
|
|
|
|
|
das tatsaechliche Setzen eines Pixels erfolgt (am Beginn der Schleife oder
|
|
|
|
|
nachdem der Stack mit Nachbarinformationen aktualisiert wurde). Nutzen
|
|
|
|
|
Sie "canvas.set_pixel" um einen Pixel zu setzen und "canvas.get_pixel" um
|
|
|
|
|
den Zustand eines Pixels zu erhalten.
|
|
|
|
|
*************/
|
|
|
|
|
|
|
|
|
|
// Put the initial pixel into the stack
|
2019-05-18 18:53:32 +00:00
|
|
|
|
if (!canvas.get_pixel(x, y))
|
|
|
|
|
{
|
|
|
|
|
p.x = x;
|
|
|
|
|
p.y = y;
|
2019-05-11 08:51:24 +00:00
|
|
|
|
stack.push_back(p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// While there are pixels to be checked
|
2019-05-18 18:53:32 +00:00
|
|
|
|
while (!stack.empty())
|
|
|
|
|
{
|
|
|
|
|
int x = stack.front().x;
|
|
|
|
|
int y = stack.front().y;
|
2019-05-11 08:51:24 +00:00
|
|
|
|
// Complete the algorithm here
|
|
|
|
|
|
2019-05-18 18:53:32 +00:00
|
|
|
|
if (!canvas.get_pixel(x, y))
|
|
|
|
|
{
|
|
|
|
|
canvas.set_pixel(x, y);
|
|
|
|
|
|
|
|
|
|
// add neighbours with bounds check
|
|
|
|
|
if (x > 0)
|
|
|
|
|
{
|
|
|
|
|
stack.emplace_back(x - 1, y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (y > 0)
|
|
|
|
|
{
|
|
|
|
|
stack.emplace_back(x, y - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (y < canvas.get_height() - 1)
|
|
|
|
|
{
|
|
|
|
|
stack.emplace_back(x, y + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (x < canvas.get_width() - 1)
|
|
|
|
|
{
|
|
|
|
|
stack.emplace_back(x + 1, y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stack.pop_front();
|
2019-05-11 08:51:24 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Put debug output into the stream "stream" to be displayed in the
|
|
|
|
|
// main window
|
2019-05-18 18:53:32 +00:00
|
|
|
|
void non_recursive_fill_tool::set_text(std::stringstream &stream)
|
2019-05-11 08:51:24 +00:00
|
|
|
|
{
|
2019-05-18 18:53:32 +00:00
|
|
|
|
stream << "Tool: Non-Recursive Fill (click to fill)";
|
2019-05-11 08:51:24 +00:00
|
|
|
|
}
|