Implement fill algorithms
This commit is contained in:
parent
4ddcbccd01
commit
0f847a08ab
4 changed files with 99 additions and 59 deletions
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
@ -35,6 +35,8 @@
|
|||
"typeinfo": "cpp",
|
||||
"utility": "cpp",
|
||||
"__config": "cpp",
|
||||
"__nullptr": "cpp"
|
||||
"__nullptr": "cpp",
|
||||
"deque": "cpp",
|
||||
"algorithm": "cpp"
|
||||
}
|
||||
}
|
|
@ -16,11 +16,6 @@ bresenham_line_tool::bresenham_line_tool(canvas_buffer &canvas) : tool_base(canv
|
|||
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)
|
||||
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.
|
||||
*************/
|
||||
|
||||
std::cout << "first: " << std::endl;
|
||||
print_point(x0, y0);
|
||||
print_point(x1, y1);
|
||||
|
||||
if (x0 > x1)
|
||||
{
|
||||
std::swap(x0, x1);
|
||||
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;
|
||||
|
||||
if (y0 > y1)
|
||||
|
|
|
@ -6,21 +6,29 @@
|
|||
#include "non_recursive_fill_tool.h"
|
||||
#include <deque>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// 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
|
||||
shape = TS_NONE;
|
||||
is_draggable = false;
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
|
||||
void print_point(int x, int y)
|
||||
{
|
||||
std::cout << "point (" << x << ", " << y << ")" << std::endl;
|
||||
}
|
||||
|
||||
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
|
||||
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.
|
||||
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
|
||||
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
|
||||
ergaenzen. Bevor Sie beginnen machen Sie sich Gedanken an welcher Stelle
|
||||
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.
|
||||
*************/
|
||||
|
||||
|
||||
|
||||
// Put the initial pixel into the stack
|
||||
if (!canvas.get_pixel(x, y)) {
|
||||
if (!canvas.get_pixel(x, y))
|
||||
{
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
canvas.set_pixel(x, y);
|
||||
stack.push_back(p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// While there are pixels to be checked
|
||||
while (!stack.empty()) {
|
||||
|
||||
int cur_x = stack.front().x;
|
||||
int cur_y = stack.front().y;
|
||||
while (!stack.empty())
|
||||
{
|
||||
int x = stack.front().x;
|
||||
int y = stack.front().y;
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Put debug output into the stream "stream" to be displayed in the
|
||||
// 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)";
|
||||
}
|
|
@ -6,15 +6,13 @@
|
|||
#include "recursive_fill_tool.h"
|
||||
|
||||
// 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
|
||||
shape = TS_NONE;
|
||||
is_draggable = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Fill the shape that contains the point (x, 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)".
|
||||
This method will make the application crash if the area which shall
|
||||
be filled is too big.
|
||||
Aufgabe 3.2.1. Implementieren Sie den rekursiven Füllalgorithmus, indem Sie den
|
||||
Zustand der Nachbarpixel überprüfen (mittels "canvas.get_pixel(x, y)"
|
||||
wobei "x" und "y" die Position des zu überprüfenden Pixels definieren)
|
||||
Aufgabe 3.2.1. Implementieren Sie den rekursiven F<EFBFBD>llalgorithmus, indem Sie den
|
||||
Zustand der Nachbarpixel <EFBFBD>berpr<EFBFBD>fen (mittels "canvas.get_pixel(x, y)"
|
||||
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
|
||||
gesetzt sind. Ein Pixel kann durch "canvas.set_pixel(x, y)" gesetzt
|
||||
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
|
||||
// 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)";
|
||||
}
|
Loading…
Reference in a new issue