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",
|
"typeinfo": "cpp",
|
||||||
"utility": "cpp",
|
"utility": "cpp",
|
||||||
"__config": "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;
|
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)
|
||||||
|
|
|
@ -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)";
|
||||||
}
|
}
|
|
@ -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)";
|
||||||
}
|
}
|
Loading…
Reference in a new issue