Compare commits
2 Commits
6bbdf004bd
...
2b299060f9
Author | SHA1 | Date | |
---|---|---|---|
2b299060f9 | |||
5729315c09 |
204
Display.cpp
204
Display.cpp
@ -98,6 +98,60 @@ void Display::show()
|
||||
}
|
||||
}
|
||||
|
||||
void Display::setCurrentLine()
|
||||
{
|
||||
while (m_curLineIdx == -1)
|
||||
{
|
||||
size_t lines = m_lines.size();
|
||||
if (lines < 1) // no more open lines -> fin
|
||||
{
|
||||
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");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Line cand = m_lines[lines - 1];
|
||||
int positives = 0;
|
||||
for (auto& pt : m_points)
|
||||
{
|
||||
if (cand.is_point_right(Point(pt.getPosition().x, pt.getPosition().y)))
|
||||
{
|
||||
positives++;
|
||||
break; // sufficient as candidate if at least one point is right
|
||||
}
|
||||
/*positives += (sign(pt.getPosition().x, pt.getPosition().y,
|
||||
cand.from().x(), cand.from().y(),
|
||||
cand.to().x(), cand.to().y()) > 0) ? 1 : 0;*/
|
||||
}
|
||||
|
||||
if (positives > 0)
|
||||
{
|
||||
m_curLineIdx = lines - 1;
|
||||
m_curLine = m_lines[lines - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lines.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& pt : m_points)
|
||||
{
|
||||
pt.setFillColor(sign(
|
||||
pt.getPosition().x, pt.getPosition().y,
|
||||
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
|
||||
@ -116,29 +170,88 @@ void Display::update ()
|
||||
// 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);
|
||||
sf::Vector2f left(WIDTH, HEIGHT);
|
||||
sf::Vector2f right(0, HEIGHT);
|
||||
sf::Vector2f bot(0, 0);
|
||||
sf::Vector2f top(0, HEIGHT);
|
||||
|
||||
for (auto& pt : m_points)
|
||||
// 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 = pt.getPosition();
|
||||
sf::Vector2f pos = m_points[i].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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
// 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
|
||||
{
|
||||
@ -165,6 +278,7 @@ void Display::update ()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: split points and use map
|
||||
// adding starting points from most x to left
|
||||
if (i_left < i_right)
|
||||
{
|
||||
@ -172,18 +286,18 @@ void Display::update ()
|
||||
}
|
||||
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);
|
||||
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];
|
||||
|
||||
// TODO: split points and use map
|
||||
}
|
||||
}
|
||||
else if (curStep == 2)
|
||||
@ -192,49 +306,7 @@ void Display::update ()
|
||||
m_textStatus.setString(text + "split board...");
|
||||
|
||||
// get current line with points
|
||||
while (m_curLineIdx == -1)
|
||||
{
|
||||
size_t lines = m_lines.size();
|
||||
if (lines < 1) // no more open lines -> fin
|
||||
{
|
||||
std::cout << "## no more open lines -> fin!" << std::endl;
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
Line cand = m_lines[lines - 1];
|
||||
int positives = 0;
|
||||
for (auto& pt : m_points)
|
||||
{
|
||||
if (cand.is_point_right(Point(pt.getPosition().x, pt.getPosition().y)))
|
||||
{
|
||||
positives++;
|
||||
break; // sufficient as candidate if at least one point is right
|
||||
}
|
||||
/*positives += (sign(pt.getPosition().x, pt.getPosition().y,
|
||||
cand.from().x(), cand.from().y(),
|
||||
cand.to().x(), cand.to().y()) > 0) ? 1 : 0;*/
|
||||
}
|
||||
|
||||
if (positives > 0)
|
||||
{
|
||||
m_curLineIdx = lines - 1;
|
||||
m_curLine = m_lines[lines - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lines.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& pt : m_points)
|
||||
{
|
||||
pt.setFillColor(sign(
|
||||
pt.getPosition().x, pt.getPosition().y,
|
||||
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);
|
||||
}
|
||||
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,6 +44,8 @@ private:
|
||||
int m_curLineIdx = -1; // or just use index
|
||||
|
||||
unsigned int m_step = 0;
|
||||
|
||||
void setCurrentLine();
|
||||
void update();
|
||||
void render(sf::RenderWindow &);
|
||||
|
||||
|
@ -58,8 +58,11 @@ public:
|
||||
{
|
||||
std::list<Point> points;
|
||||
|
||||
//srand(static_cast <unsigned> (time(0)));
|
||||
#ifdef _DEBUG
|
||||
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,4 +22,17 @@ 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