Implement fill algorithms

This commit is contained in:
hodasemi 2019-05-18 20:53:32 +02:00
parent 4ddcbccd01
commit 0f847a08ab
4 changed files with 99 additions and 59 deletions

View file

@ -35,6 +35,8 @@
"typeinfo": "cpp", "typeinfo": "cpp",
"utility": "cpp", "utility": "cpp",
"__config": "cpp", "__config": "cpp",
"__nullptr": "cpp" "__nullptr": "cpp",
"deque": "cpp",
"algorithm": "cpp"
} }
} }

View file

@ -16,11 +16,6 @@ bresenham_line_tool::bresenham_line_tool(canvas_buffer &canvas) : tool_base(canv
shape = TS_LINE; shape = TS_LINE;
} }
void print_point(int x, int y)
{
std::cout << "point (" << x << ", " << y << ")" << std::endl;
}
// Draw a line from (x0, y0) to (x1, y1) // Draw a line from (x0, y0) to (x1, y1)
void bresenham_line_tool::draw(int x0, int y0, int x1, int y1) void bresenham_line_tool::draw(int x0, int y0, int x1, int y1)
{ {
@ -40,21 +35,12 @@ void bresenham_line_tool::draw(int x0, int y0, int x1, int y1)
muessen koennen Sie dafür die Methode "std::swap(a, b)" verwenden. muessen koennen Sie dafür die Methode "std::swap(a, b)" verwenden.
*************/ *************/
std::cout << "first: " << std::endl;
print_point(x0, y0);
print_point(x1, y1);
if (x0 > x1) if (x0 > x1)
{ {
std::swap(x0, x1); std::swap(x0, x1);
std::swap(y0, y1); std::swap(y0, y1);
} }
std::cout << "second: " << std::endl;
print_point(x0, y0);
print_point(x1, y1);
std::cout << std::endl;
bool swap_y = false; bool swap_y = false;
if (y0 > y1) if (y0 > y1)

View file

@ -6,21 +6,29 @@
#include "non_recursive_fill_tool.h" #include "non_recursive_fill_tool.h"
#include <deque> #include <deque>
#include <iostream>
// Initialize the tool and store a reference of a canvas_buffer // Initialize the tool and store a reference of a canvas_buffer
non_recursive_fill_tool::non_recursive_fill_tool(canvas_buffer& canvas): tool_base(canvas) non_recursive_fill_tool::non_recursive_fill_tool(canvas_buffer &canvas) : tool_base(canvas)
{ {
// This tool has no shape and is not draggable // This tool has no shape and is not draggable
shape = TS_NONE; shape = TS_NONE;
is_draggable = false; is_draggable = false;
} }
// A pixel to be put into the queue of pixels to process // A pixel to be put into the queue of pixels to process
struct waiting_pixel { struct waiting_pixel
{
waiting_pixel(int x, int y) : x(x), y(y) {}
waiting_pixel() : x(0), y(0) {}
int x, y; int x, y;
}; };
void print_point(int x, int y)
{
std::cout << "point (" << x << ", " << y << ")" << std::endl;
}
void non_recursive_fill_tool::draw(int x, int y) void non_recursive_fill_tool::draw(int x, int y)
{ {
@ -35,10 +43,10 @@ void non_recursive_fill_tool::draw(int x, int y)
think about when to set the pixel (at the beginning of the loop or after think about when to set the pixel (at the beginning of the loop or after
the stack was updated with neighbours). Use "canvas.set_pixel" to set 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. a pixel and "canvas.get_pixel" to read the state of a pixel.
Aufgabe 3.2.2. Implementieren Sie einen Füllalgorithmus ohne Rekursion zu verwenden. Aufgabe 3.2.2. Implementieren Sie einen F<EFBFBD>llalgorithmus ohne Rekursion zu verwenden.
Nutzen Sie stattdessen einen Stack. Der vorgegebene Quelltext unten fuegt Nutzen Sie stattdessen einen Stack. Der vorgegebene Quelltext unten fuegt
das erste Element in den Stack ein und startet eine Schleife, die das das erste Element in den Stack ein und startet eine Schleife, die das
vorderste Element aus dem Stack liest und es anschließend entfernt. vorderste Element aus dem Stack liest und es anschlie<EFBFBD>end entfernt.
Ihre Aufgabe ist es die Funktionalitaet im Inneren der Schleife zu Ihre Aufgabe ist es die Funktionalitaet im Inneren der Schleife zu
ergaenzen. Bevor Sie beginnen machen Sie sich Gedanken an welcher Stelle ergaenzen. Bevor Sie beginnen machen Sie sich Gedanken an welcher Stelle
das tatsaechliche Setzen eines Pixels erfolgt (am Beginn der Schleife oder das tatsaechliche Setzen eines Pixels erfolgt (am Beginn der Schleife oder
@ -47,34 +55,54 @@ void non_recursive_fill_tool::draw(int x, int y)
den Zustand eines Pixels zu erhalten. den Zustand eines Pixels zu erhalten.
*************/ *************/
// Put the initial pixel into the stack // Put the initial pixel into the stack
if (!canvas.get_pixel(x, y)) { if (!canvas.get_pixel(x, y))
{
p.x = x; p.x = x;
p.y = y; p.y = y;
canvas.set_pixel(x, y);
stack.push_back(p); stack.push_back(p);
} }
// While there are pixels to be checked // While there are pixels to be checked
while (!stack.empty()) { while (!stack.empty())
{
int cur_x = stack.front().x; int x = stack.front().x;
int cur_y = stack.front().y; int y = stack.front().y;
// Complete the algorithm here // Complete the algorithm here
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(); stack.pop_front();
} }
} }
// Put debug output into the stream "stream" to be displayed in the // Put debug output into the stream "stream" to be displayed in the
// main window // main window
void non_recursive_fill_tool::set_text(std::stringstream& stream) void non_recursive_fill_tool::set_text(std::stringstream &stream)
{ {
stream<<"Tool: Non-Recursive Fill (click to fill)"; stream << "Tool: Non-Recursive Fill (click to fill)";
} }

View file

@ -6,15 +6,13 @@
#include "recursive_fill_tool.h" #include "recursive_fill_tool.h"
// Initialize the tool and store a reference of a canvas_buffer // Initialize the tool and store a reference of a canvas_buffer
recursive_fill_tool::recursive_fill_tool(canvas_buffer& canvas): tool_base(canvas) recursive_fill_tool::recursive_fill_tool(canvas_buffer &canvas) : tool_base(canvas)
{ {
// This tool has no shape and is not draggable // This tool has no shape and is not draggable
shape = TS_NONE; shape = TS_NONE;
is_draggable = false; is_draggable = false;
} }
// Fill the shape that contains the point (x, y) // Fill the shape that contains the point (x, y)
void recursive_fill_tool::draw(int x, int y) void recursive_fill_tool::draw(int x, int y)
{ {
@ -26,20 +24,46 @@ void recursive_fill_tool::draw(int x, int y)
"canvas.set_pixel(x, y)". "canvas.set_pixel(x, y)".
This method will make the application crash if the area which shall This method will make the application crash if the area which shall
be filled is too big. be filled is too big.
Aufgabe 3.2.1. Implementieren Sie den rekursiven Füllalgorithmus, indem Sie den Aufgabe 3.2.1. Implementieren Sie den rekursiven F<EFBFBD>llalgorithmus, indem Sie den
Zustand der Nachbarpixel überprüfen (mittels "canvas.get_pixel(x, y)" Zustand der Nachbarpixel <EFBFBD>berpr<EFBFBD>fen (mittels "canvas.get_pixel(x, y)"
wobei "x" und "y" die Position des zu überprüfenden Pixels definieren) wobei "x" und "y" die Position des zu <EFBFBD>berpr<EFBFBD>fenden Pixels definieren)
und rufen Sie rekursiv die "draw"-Methode auf, wenn die Pixel nicht und rufen Sie rekursiv die "draw"-Methode auf, wenn die Pixel nicht
gesetzt sind. Ein Pixel kann durch "canvas.set_pixel(x, y)" gesetzt gesetzt sind. Ein Pixel kann durch "canvas.set_pixel(x, y)" gesetzt
werden. werden.
*************/ *************/
if (canvas.get_pixel(x, y))
{
return;
}
canvas.set_pixel(x, y);
// call neighbours with bounds check
if (x > 0)
{
draw(x - 1, y);
}
if (y > 0)
{
draw(x, y - 1);
}
if (y < canvas.get_height() - 1)
{
draw(x, y + 1);
}
if (x < canvas.get_width() - 1)
{
draw(x + 1, y);
}
} }
// Put debug output into the stream "stream" to be displayed in the // Put debug output into the stream "stream" to be displayed in the
// main window // main window
void recursive_fill_tool::set_text(std::stringstream& stream) void recursive_fill_tool::set_text(std::stringstream &stream)
{ {
stream<<"Tool: Recursive Fill (click to fill)"; stream << "Tool: Recursive Fill (click to fill)";
} }