Compare commits
No commits in common. "2b299060f9ce9bae1eb27eada9aabb540221ad7a" and "6bbdf004bd9fda7c8e49fc0a5eb1f5ef2145bf4f" have entirely different histories.
2b299060f9
...
6bbdf004bd
260
Display.cpp
260
Display.cpp
@ -98,8 +98,100 @@ void Display::show()
|
||||
}
|
||||
}
|
||||
|
||||
void Display::setCurrentLine()
|
||||
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 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)
|
||||
{
|
||||
size_t lines = m_lines.size();
|
||||
@ -107,14 +199,7 @@ void Display::setCurrentLine()
|
||||
{
|
||||
std::cout << "## no more open lines -> fin!" << std::endl;
|
||||
m_points.clear();
|
||||
|
||||
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");
|
||||
}
|
||||
if (m_points.size() == 0) m_textStatus.setString(text + "finished calculating convex hull in " + std::to_string((m_step / 4 + 1)) + " cycles");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -150,163 +235,6 @@ void Display::setCurrentLine()
|
||||
m_lines[m_curLineIdx].from().x(), m_lines[m_curLineIdx].from().y(),
|
||||
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)
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ private:
|
||||
|
||||
//std::vector<sf::Vertex> m_hull;
|
||||
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
|
||||
|
||||
//std::map<Line, std::vector<Point> > m_pointsForLine;
|
||||
@ -44,8 +44,6 @@ private:
|
||||
int m_curLineIdx = -1; // or just use index
|
||||
|
||||
unsigned int m_step = 0;
|
||||
|
||||
void setCurrentLine();
|
||||
void update();
|
||||
void render(sf::RenderWindow &);
|
||||
|
||||
|
@ -58,11 +58,8 @@ public:
|
||||
{
|
||||
std::list<Point> points;
|
||||
|
||||
#ifdef _DEBUG
|
||||
//srand(static_cast <unsigned> (time(0)));
|
||||
srand(static_cast <unsigned> (0)); // fixed seed for testing
|
||||
#else
|
||||
srand(static_cast <unsigned> (time(0)));
|
||||
#endif
|
||||
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
|
13
Utility.h
13
Utility.h
@ -22,17 +22,4 @@ static bool IsPointInTriangle(const Point &pt, const Point &p1, const Point &p2,
|
||||
|
||||
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
|
Loading…
x
Reference in New Issue
Block a user