Compare commits
2 Commits
6bbdf004bd
...
2b299060f9
Author | SHA1 | Date | |
---|---|---|---|
2b299060f9 | |||
5729315c09 |
260
Display.cpp
260
Display.cpp
@ -98,100 +98,8 @@ void Display::show()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::update ()
|
void Display::setCurrentLine()
|
||||||
{
|
{
|
||||||
unsigned int curStep = (m_step > 5) ? ((m_step - 2) % 4 + 2) : (m_step % 6); // skip init and first step after first run
|
|
||||||
if (m_stepSize == 0 && curStep > 0)
|
|
||||||
{
|
|
||||||
std::cout << "any key to continue with next step...";
|
|
||||||
std::cin.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string text = "(" + std::to_string(m_step) + ") step " + std::to_string(curStep) + ": ";
|
|
||||||
if (curStep == 1)
|
|
||||||
{
|
|
||||||
// first step: select min - max x coordinates
|
|
||||||
m_textStatus.setString(text + "select min - max x coordinates...");
|
|
||||||
|
|
||||||
// if use Akl–Toussaint heuristic
|
|
||||||
if (m_useAkl)
|
|
||||||
{
|
|
||||||
sf::Vector2f topLeft(WIDTH, HEIGHT);
|
|
||||||
sf::Vector2f topRight(0, HEIGHT);
|
|
||||||
sf::Vector2f botLeft(WIDTH, 0);
|
|
||||||
sf::Vector2f botRight(0, 0);
|
|
||||||
|
|
||||||
for (auto& pt : m_points)
|
|
||||||
{
|
|
||||||
sf::Vector2f pos = pt.getPosition();
|
|
||||||
float x = pos.x;
|
|
||||||
float y = pos.y;
|
|
||||||
// TODO: only check explicit x and y seperate!
|
|
||||||
if (x < topLeft.x && y < topLeft.y) topLeft = pos;
|
|
||||||
if (x > topRight.x && y < topLeft.y) topRight = pos;
|
|
||||||
if (x < botLeft.x && y > botLeft.y) botLeft = pos;
|
|
||||||
if (x > botRight.x && y > botRight.y) botRight = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_hull.setPrimitiveType(sf::LineStrip);
|
|
||||||
m_hull.append(sf::Vertex(topLeft, sf::Color::Blue));
|
|
||||||
m_hull.append(sf::Vertex(topRight, sf::Color::Blue));
|
|
||||||
m_hull.append(sf::Vertex(botRight, sf::Color::Blue));
|
|
||||||
m_hull.append(sf::Vertex(botLeft, sf::Color::Blue));
|
|
||||||
m_hull.append(sf::Vertex(topLeft, sf::Color::Blue));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sf::Vector2f left(WIDTH, HEIGHT);
|
|
||||||
sf::Vector2f right(0, 0);
|
|
||||||
|
|
||||||
int i_left = WIDTH;
|
|
||||||
int i_right = 0;
|
|
||||||
|
|
||||||
size_t points = m_points.size();
|
|
||||||
for (size_t i = 0; i < points; ++i)
|
|
||||||
{
|
|
||||||
sf::Vector2f pos = m_points[i].getPosition();
|
|
||||||
float x = pos.x;
|
|
||||||
if (x < left.x)
|
|
||||||
{
|
|
||||||
i_left = i;
|
|
||||||
left = pos;
|
|
||||||
}
|
|
||||||
if (x > right.x)
|
|
||||||
{
|
|
||||||
i_right = i;
|
|
||||||
right = pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// adding starting points from most x to left
|
|
||||||
if (i_left < i_right)
|
|
||||||
{
|
|
||||||
std::swap(i_left, i_right);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 2; ++i)
|
|
||||||
{
|
|
||||||
int pos = (i == 0) ? i_left : i_right;
|
|
||||||
m_points[pos].setFillColor(sf::Color::Blue);
|
|
||||||
m_hullPoints.push_back(m_points[pos]);
|
|
||||||
m_points.erase(m_points.begin() + pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_lines.push_back(Line(Point(left.x, left.y), Point(right.x, right.y)));
|
|
||||||
m_lines.push_back(Line(Point(right.x, right.y), Point(left.x, left.y))); // add first line in both directions to work with "right side"
|
|
||||||
m_curLineIdx = 1;
|
|
||||||
m_curLine = m_lines[1];
|
|
||||||
|
|
||||||
// TODO: split points and use map
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (curStep == 2)
|
|
||||||
{
|
|
||||||
// second step: split board
|
|
||||||
m_textStatus.setString(text + "split board...");
|
|
||||||
|
|
||||||
// get current line with points
|
|
||||||
while (m_curLineIdx == -1)
|
while (m_curLineIdx == -1)
|
||||||
{
|
{
|
||||||
size_t lines = m_lines.size();
|
size_t lines = m_lines.size();
|
||||||
@ -199,7 +107,14 @@ void Display::update ()
|
|||||||
{
|
{
|
||||||
std::cout << "## no more open lines -> fin!" << std::endl;
|
std::cout << "## no more open lines -> fin!" << std::endl;
|
||||||
m_points.clear();
|
m_points.clear();
|
||||||
if (m_points.size() == 0) m_textStatus.setString(text + "finished calculating convex hull in " + std::to_string((m_step / 4 + 1)) + " cycles");
|
|
||||||
|
if (m_points.size() == 0)
|
||||||
|
{
|
||||||
|
unsigned int curStep = (m_step > 5) ? ((m_step - 2) % 4 + 2) : (m_step % 6); // skip init and first step after first run
|
||||||
|
|
||||||
|
std::string text = "(" + std::to_string(m_step) + ") step " + std::to_string(curStep) + ": ";
|
||||||
|
m_textStatus.setString(text + "finished calculating convex hull in " + std::to_string((m_step / 4 + 1)) + " cycles");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,6 +151,163 @@ void Display::update ()
|
|||||||
m_lines[m_curLineIdx].to().x(), m_lines[m_curLineIdx].to().y()) > 0 ? sf::Color::Red : sf::Color::Green);
|
m_lines[m_curLineIdx].to().x(), m_lines[m_curLineIdx].to().y()) > 0 ? sf::Color::Red : sf::Color::Green);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Display::update ()
|
||||||
|
{
|
||||||
|
unsigned int curStep = (m_step > 5) ? ((m_step - 2) % 4 + 2) : (m_step % 6); // skip init and first step after first run
|
||||||
|
if (m_stepSize == 0 && curStep > 0)
|
||||||
|
{
|
||||||
|
std::cout << "any key to continue with next step...";
|
||||||
|
std::cin.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string text = "(" + std::to_string(m_step) + ") step " + std::to_string(curStep) + ": ";
|
||||||
|
if (curStep == 1)
|
||||||
|
{
|
||||||
|
// first step: select min - max x coordinates
|
||||||
|
m_textStatus.setString(text + "select min - max x coordinates...");
|
||||||
|
|
||||||
|
// if use Akl–Toussaint heuristic
|
||||||
|
if (m_useAkl)
|
||||||
|
{
|
||||||
|
sf::Vector2f left(WIDTH, HEIGHT);
|
||||||
|
sf::Vector2f right(0, HEIGHT);
|
||||||
|
sf::Vector2f bot(0, 0);
|
||||||
|
sf::Vector2f top(0, HEIGHT);
|
||||||
|
|
||||||
|
// index to find points
|
||||||
|
int i_left = WIDTH;
|
||||||
|
int i_right = 0;
|
||||||
|
int i_top = HEIGHT;
|
||||||
|
int i_bot = 0;
|
||||||
|
|
||||||
|
size_t points = m_points.size();
|
||||||
|
for (size_t i = 0; i < points; ++i)
|
||||||
|
{
|
||||||
|
sf::Vector2f pos = m_points[i].getPosition();
|
||||||
|
float x = pos.x;
|
||||||
|
float y = pos.y;
|
||||||
|
if (x < left.x)
|
||||||
|
{
|
||||||
|
left = pos;
|
||||||
|
i_left = i;
|
||||||
|
}
|
||||||
|
if (x > right.x)
|
||||||
|
{
|
||||||
|
right = pos;
|
||||||
|
i_right = i;
|
||||||
|
}
|
||||||
|
if (y < top.y)
|
||||||
|
{
|
||||||
|
top = pos;
|
||||||
|
i_top = i;
|
||||||
|
}
|
||||||
|
if (y > bot.y)
|
||||||
|
{
|
||||||
|
bot = pos;
|
||||||
|
i_bot = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// adding edge points to hull
|
||||||
|
m_points[i_left].setFillColor(sf::Color::Blue);
|
||||||
|
m_hullPoints.push_back(m_points[i_left]);
|
||||||
|
|
||||||
|
m_points[i_top].setFillColor(sf::Color::Blue);
|
||||||
|
m_hullPoints.push_back(m_points[i_top]);
|
||||||
|
|
||||||
|
m_points[i_right].setFillColor(sf::Color::Blue);
|
||||||
|
m_hullPoints.push_back(m_points[i_right]);
|
||||||
|
|
||||||
|
m_points[i_bot].setFillColor(sf::Color::Blue);
|
||||||
|
m_hullPoints.push_back(m_points[i_bot]);
|
||||||
|
|
||||||
|
// building lines between edge points
|
||||||
|
Point pt1(left.x, left.y);
|
||||||
|
Point pt2(top.x, top.y);
|
||||||
|
Point pt3(right.x, right.y);
|
||||||
|
Point pt4(bot.x, bot.y);
|
||||||
|
m_lines.push_back(Line(pt1, pt2));
|
||||||
|
m_lines.push_back(Line(pt2, pt3));
|
||||||
|
m_lines.push_back(Line(pt3, pt4));
|
||||||
|
m_lines.push_back(Line(pt4, pt1));
|
||||||
|
|
||||||
|
// remove points in calculated rectangle
|
||||||
|
for (int i = points - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
Point pt(m_points[i].getPosition().x, m_points[i].getPosition().y);
|
||||||
|
if (IsPointInRectangle(pt, pt1, pt2, pt3, pt4))
|
||||||
|
{
|
||||||
|
std::cout << "remove pt inside triangle -> " << i << " with pos: " << pt.x() << ", " << pt.y() << std::endl;
|
||||||
|
m_points.erase(m_points.begin() + i);
|
||||||
|
}
|
||||||
|
// TODO: ugly workaround - remove hull points
|
||||||
|
else if ((pt.x() == pt1.x() && pt.y() == pt1.y()) ||
|
||||||
|
(pt.x() == pt2.x() && pt.y() == pt2.y()) ||
|
||||||
|
(pt.x() == pt3.x() && pt.y() == pt3.y()) ||
|
||||||
|
(pt.x() == pt4.x() && pt.y() == pt4.y()))
|
||||||
|
{
|
||||||
|
m_points.erase(m_points.begin() + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentLine();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sf::Vector2f left(WIDTH, HEIGHT);
|
||||||
|
sf::Vector2f right(0, 0);
|
||||||
|
|
||||||
|
int i_left = WIDTH;
|
||||||
|
int i_right = 0;
|
||||||
|
|
||||||
|
size_t points = m_points.size();
|
||||||
|
for (size_t i = 0; i < points; ++i)
|
||||||
|
{
|
||||||
|
sf::Vector2f pos = m_points[i].getPosition();
|
||||||
|
float x = pos.x;
|
||||||
|
if (x < left.x)
|
||||||
|
{
|
||||||
|
i_left = i;
|
||||||
|
left = pos;
|
||||||
|
}
|
||||||
|
if (x > right.x)
|
||||||
|
{
|
||||||
|
i_right = i;
|
||||||
|
right = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: split points and use map
|
||||||
|
// adding starting points from most x to left
|
||||||
|
if (i_left < i_right)
|
||||||
|
{
|
||||||
|
std::swap(i_left, i_right);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 2; ++i)
|
||||||
|
{
|
||||||
|
int idx = (i == 0) ? i_left : i_right;
|
||||||
|
m_points[idx].setFillColor(sf::Color::Blue);
|
||||||
|
m_hullPoints.push_back(m_points[idx]);
|
||||||
|
m_points.erase(m_points.begin() + idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lines.push_back(Line(Point(left.x, left.y), Point(right.x, right.y)));
|
||||||
|
m_lines.push_back(Line(Point(right.x, right.y), Point(left.x, left.y))); // add first line in both directions to work with "right side"
|
||||||
|
|
||||||
|
// set current line just by taking the only one (in one direction)
|
||||||
|
m_curLineIdx = 1;
|
||||||
|
m_curLine = m_lines[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (curStep == 2)
|
||||||
|
{
|
||||||
|
// second step: split board
|
||||||
|
m_textStatus.setString(text + "split board...");
|
||||||
|
|
||||||
|
// get current line with points
|
||||||
|
setCurrentLine();
|
||||||
|
}
|
||||||
else if (curStep == 3)
|
else if (curStep == 3)
|
||||||
{
|
{
|
||||||
// get line with more than one point -> or use m_curLine
|
// get line with more than one point -> or use m_curLine
|
||||||
|
@ -33,7 +33,7 @@ private:
|
|||||||
|
|
||||||
//std::vector<sf::Vertex> m_hull;
|
//std::vector<sf::Vertex> m_hull;
|
||||||
std::vector<sf::CircleShape> m_hullPoints;
|
std::vector<sf::CircleShape> m_hullPoints;
|
||||||
sf::VertexArray m_hull;
|
//sf::VertexArray m_hull;
|
||||||
//sf::ConvexShape m_convex; // shape for convex hull -> does not fit because points have to be aligned already
|
//sf::ConvexShape m_convex; // shape for convex hull -> does not fit because points have to be aligned already
|
||||||
|
|
||||||
//std::map<Line, std::vector<Point> > m_pointsForLine;
|
//std::map<Line, std::vector<Point> > m_pointsForLine;
|
||||||
@ -44,6 +44,8 @@ private:
|
|||||||
int m_curLineIdx = -1; // or just use index
|
int m_curLineIdx = -1; // or just use index
|
||||||
|
|
||||||
unsigned int m_step = 0;
|
unsigned int m_step = 0;
|
||||||
|
|
||||||
|
void setCurrentLine();
|
||||||
void update();
|
void update();
|
||||||
void render(sf::RenderWindow &);
|
void render(sf::RenderWindow &);
|
||||||
|
|
||||||
|
@ -58,8 +58,11 @@ public:
|
|||||||
{
|
{
|
||||||
std::list<Point> points;
|
std::list<Point> points;
|
||||||
|
|
||||||
//srand(static_cast <unsigned> (time(0)));
|
#ifdef _DEBUG
|
||||||
srand(static_cast <unsigned> (0)); // fixed seed for testing
|
srand(static_cast <unsigned> (0)); // fixed seed for testing
|
||||||
|
#else
|
||||||
|
srand(static_cast <unsigned> (time(0)));
|
||||||
|
#endif
|
||||||
|
|
||||||
float x = 0;
|
float x = 0;
|
||||||
float y = 0;
|
float y = 0;
|
||||||
|
13
Utility.h
13
Utility.h
@ -22,4 +22,17 @@ static bool IsPointInTriangle(const Point &pt, const Point &p1, const Point &p2,
|
|||||||
|
|
||||||
return !(has_neg && has_pos);
|
return !(has_neg && has_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool IsPointInRectangle(const Point& pt, const Point& p1, const Point& p2, const Point& p3, const Point& p4)
|
||||||
|
{
|
||||||
|
float d1 = sign(pt, p1, p2);
|
||||||
|
float d2 = sign(pt, p2, p3);
|
||||||
|
float d3 = sign(pt, p3, p4);
|
||||||
|
float d4 = sign(pt, p4, p1);
|
||||||
|
|
||||||
|
bool has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0) || (d4 < 0);
|
||||||
|
bool has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0) || (d4 > 0);
|
||||||
|
|
||||||
|
return !(has_neg && has_pos);
|
||||||
|
}
|
||||||
#endif // UTILITY_H
|
#endif // UTILITY_H
|
Loading…
x
Reference in New Issue
Block a user