Compare commits

...

2 Commits

3 changed files with 124 additions and 29 deletions

View File

@ -4,12 +4,13 @@
#include <thread> #include <thread>
#include "Display.h" #include "Display.h"
//#include "Line.h"
#include "Point.h" #include "Point.h"
#include "Utility.h" #include "Utility.h"
Display::Display (const std::vector<Point> &pts) Display::Display (const std::vector<Point> &pts)
{ {
if (!m_font.loadFromFile("LiberationSans-Regular.ttf")) if (!m_font.loadFromFile("Resources/LiberationSans-Regular.ttf"))
{ {
std::cerr << "font LiberationSans-Regular.ttf could not be loaded!" << std::endl; std::cerr << "font LiberationSans-Regular.ttf could not be loaded!" << std::endl;
} }
@ -146,12 +147,13 @@ void Display::update ()
/* TODO: use a convex shape? Or build from vertices in render? /* TODO: use a convex shape? Or build from vertices in render?
sf::ConvexShape convex; sf::ConvexShape convex;
convex.setPointCount(5); convex.setPointCount(4);
convex.setPoint(0, topLeft); convex.setPoint(0, topLeft);
convex.setPoint(0, topRight); convex.setPoint(1, topRight);
convex.setPoint(0, botRight); convex.setPoint(2, botRight);
convex.setPoint(0, botLeft);*/ convex.setPoint(3, botLeft);*/
//m_ hull as VertexArray
//m_hull.setPrimitiveType(sf::Lines); //m_hull.setPrimitiveType(sf::Lines);
m_hull.setPrimitiveType(sf::LineStrip); m_hull.setPrimitiveType(sf::LineStrip);
m_hull.append(sf::Vertex(topLeft, sf::Color::Blue)); m_hull.append(sf::Vertex(topLeft, sf::Color::Blue));
@ -169,32 +171,70 @@ void Display::update ()
{ {
sf::Vector2f pos = pt.getPosition(); sf::Vector2f pos = pt.getPosition();
float x = pos.x; float x = pos.x;
float y = pos.y; //float y = pos.y;
if (x < left.x) left = pos; if (x < left.x) left = pos;
if (x > right.x) right = pos; if (x > right.x) right = pos;
} }
//m_ hull as VertexArray
//m_hull.setPrimitiveType(sf::Lines); //m_hull.setPrimitiveType(sf::Lines);
m_hull.setPrimitiveType(sf::LineStrip); m_hull.setPrimitiveType(sf::LineStrip);
m_hull.append(sf::Vertex(left, sf::Color::Blue)); m_hull.append(sf::Vertex(left, sf::Color::Blue));
m_hull.append(sf::Vertex(right, sf::Color::Blue)); m_hull.append(sf::Vertex(right, sf::Color::Blue));
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_curLine = &m_lines[1];
// TODO: split points and use map
m_convex.setPointCount(2);
m_convex.setFillColor(sf::Color::Transparent);
m_convex.setOutlineColor(sf::Color::Red);
m_convex.setOutlineThickness(2);
m_convex.setPoint(0, left);
m_convex.setPoint(1, right);
// TODO: could add here -> set color of points for current split
} }
} }
else if (curStep == 2) else if (curStep == 2)
{ {
// second step: split board and find furthest point // second step: split board
m_textStatus.setString(text + "split board and find furthest point..."); m_textStatus.setString(text + "split board...");
// TODO: get current line with points
if (m_curLine == nullptr)
{
size_t lines = m_lines.size();
if (lines < 1) throw "no more lines to work :-o TODO: just jump to finish?";
m_curLine = &m_lines[lines - 1];
}
std::cout << std::endl << "current line: " <<
std::to_string(m_curLine->from().x()) << ", " <<
std::to_string(m_curLine->from().y()) << ", " <<
std::to_string(m_curLine->to().x()) << ", " <<
std::to_string(m_curLine->to().y()) << ", " <<
" of " << std::to_string(m_lines.size()) << std::endl;
for (auto& pt : m_points) for (auto& pt : m_points)
{ {
pt.setFillColor(sign( pt.setFillColor(sign(
pt.getPosition().x, pt.getPosition().y, pt.getPosition().x, pt.getPosition().y,
m_hull[0].position.x, m_hull[0].position.y, //m_hull[0].position.x, m_hull[0].position.y,
m_hull[1].position.x, m_hull[1].position.y) > 0 ? sf::Color::Red : sf::Color::Green); //m_hull[1].position.x, m_hull[1].position.y) > 0 ? sf::Color::Red : sf::Color::Green);
m_curLine->from().x(), m_curLine->from().y(),
m_curLine->to().x(), m_curLine->to().y()) > 0 ? sf::Color::Red : sf::Color::Green);
} }
} }
else if (curStep == 3) else if (curStep == 3)
{ {
// get line with more than one point -> or use m_curLine
// calc furthest point
// create new lines
// third step: draw triangle, remove inner points // third step: draw triangle, remove inner points
m_textStatus.setString(text + "find furthest point and draw triangle..."); m_textStatus.setString(text + "find furthest point and draw triangle...");
@ -202,11 +242,7 @@ void Display::update ()
float maxDistance = 0; float maxDistance = 0;
for (auto& pt : m_points) for (auto& pt : m_points)
{ {
float distance = pDistance( /*
pt.getPosition().x, pt.getPosition().y,
m_hull[0].position.x, m_hull[0].position.y,
m_hull[1].position.x, m_hull[1].position.y);
if (pt.getFillColor() == sf::Color::Green) if (pt.getFillColor() == sf::Color::Green)
{ {
std::cout << "distance to green point " << pt.getPosition().x << ", " << pt.getPosition().y << ": " << distance << std::endl; std::cout << "distance to green point " << pt.getPosition().x << ", " << pt.getPosition().y << ": " << distance << std::endl;
@ -215,6 +251,16 @@ void Display::update ()
{ {
std::cout << "distance to red point " << pt.getPosition().x << ", " << pt.getPosition().y << ": " << distance << std::endl; std::cout << "distance to red point " << pt.getPosition().x << ", " << pt.getPosition().y << ": " << distance << std::endl;
} }
*/
if (pt.getFillColor() != sf::Color::Green) continue;
float distance = pDistance(
pt.getPosition().x, pt.getPosition().y,
//m_hull[0].position.x, m_hull[0].position.y,
//m_hull[1].position.x, m_hull[1].position.y);
m_curLine->from().x(), m_curLine->from().y(),
m_curLine->to().x(), m_curLine->from().y());
if (distance > maxDistance) if (distance > maxDistance)
{ {
@ -225,14 +271,47 @@ void Display::update ()
if (maxDistance > 0) if (maxDistance > 0)
{ {
// TODO: not append but insert between last line points // not append but insert between last line points
// -> append a point, then swap values
size_t vertices = m_hull.getVertexCount();
m_hull.append(sf::Vertex(pos, sf::Color::Blue)); m_hull.append(sf::Vertex(pos, sf::Color::Blue));
m_hull[vertices] = m_hull[vertices - 1];
m_hull[vertices - 1] = pos;
size_t points = m_convex.getPointCount();
m_convex.setPointCount(points + 1);
m_convex.setPoint(points, pos);
//m_lines.push_back(Line(m_curLine->from(), Point(pos.x, pos.y)));
//m_lines.push_back(Line(Point(pos.x, pos.y), m_curLine->to()));
m_lines.push_back(Line(Point(pos.x, pos.y), m_curLine->to()));
m_curLine->set_to(Point(pos.x, pos.y));
}
else
{
m_lines.pop_back(); // remove last element -> TODO: directly use stack?
} }
} }
else if (curStep == 4) else if (curStep == 4)
{ {
// fourth step: remove inner points // fourth step: remove inner points
m_textStatus.setString(text + "remove inner points..."); m_textStatus.setString(text + "remove inner points...");
// TODO: wip
/*size_t lines = m_lines.size() - 1;
Point pt1 = m_lines[lines - 1].from();
Point pt2 = m_lines[lines - 1].to();
Point pt3 = m_lines[lines].to();
for (size_t i = m_points.size(); i > 0; i--)
{
Point pt(m_points[i].getPosition().x, m_points[i].getPosition().y);
if (IsPointInTriangle(pt, pt1, pt2, pt3))
{
m_points.erase(m_points.begin() + i);
}
}*/
m_curLine = nullptr;
} }
else if (curStep == 5) else if (curStep == 5)
{ {
@ -253,14 +332,16 @@ void Display::render (sf::RenderWindow &window)
{ {
window.clear(sf::Color::White); window.clear(sf::Color::White);
// always print remaining points // draw already calculated hull
/*size_t points = m_points.size(); //if (step >= 1)
for (size_t i = 0; i < points; ++i)
{ {
drawPoint(window, i); //window.draw(&m_hull[0], m_hull.size(), sf::Lines);
}*/ window.draw(&m_hull[0], m_hull.getVertexCount(), m_hull.getPrimitiveType());
//for (auto& pt : m_points) // points and labels should have the same size -> combine in one loop window.draw(m_convex);
}
// always print remaining points
size_t points = m_points.size(); size_t points = m_points.size();
for (size_t i = 0; i < points; ++i) for (size_t i = 0; i < points; ++i)
{ {
@ -268,13 +349,18 @@ void Display::render (sf::RenderWindow &window)
window.draw(m_labels[i]); window.draw(m_labels[i]);
} }
// draw already calculated hull // draw line the algorithm is currently working on
//if (step >= 1) if (m_curLine != nullptr)
{ {
//window.draw(&m_hull[0], m_hull.size(), sf::Lines); sf::Vertex line[] =
window.draw(&m_hull[0], m_hull.getVertexCount(), m_hull.getPrimitiveType()); {
sf::Vertex(sf::Vector2f(m_curLine->from().x(), m_curLine->from().y()), sf::Color::Red),
sf::Vertex(sf::Vector2f(m_curLine->to().x(), m_curLine->to().y()), sf::Color::Red)
};
window.draw(line, 2, sf::Lines);
} }
// show amount of steps and current status
window.draw(m_textStatus); window.draw(m_textStatus);
window.display(); window.display();

View File

@ -6,7 +6,11 @@
// windows - manual dl from https://www.sfml-dev.org/download.php // windows - manual dl from https://www.sfml-dev.org/download.php
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
class Point;
#include "Line.h"
//class Point;
//class Line;
#define OFFSET 10.f #define OFFSET 10.f
#define WIDTH 800 #define WIDTH 800
@ -26,6 +30,11 @@ private:
//std::vector<sf::Vertex> m_hull; //std::vector<sf::Vertex> m_hull;
sf::VertexArray m_hull; sf::VertexArray m_hull;
sf::ConvexShape m_convex;
//std::map<Line, std::vector<Point> > m_pointsForLine;
std::vector<Line> m_lines;
Line *m_curLine = nullptr;
unsigned int m_step = 0; unsigned int m_step = 0;
void update(); void update();

View File

@ -6,12 +6,12 @@ static float sign(float x, float y, float x1, float y1, float x2, float y2)
return (x - x2) * (y1 - y2) - (x1 - x2) * (y - y2); return (x - x2) * (y1 - y2) - (x1 - x2) * (y - y2);
} }
static float sign (Point &p1, Point &p2, Point &p3) static float sign (const Point &p1, const Point &p2, const Point &p3)
{ {
return (p1.x() - p3.x()) * (p2.y() - p3.y()) - (p2.x() - p3.x()) * (p1.y() - p3.y()); return (p1.x() - p3.x()) * (p2.y() - p3.y()) - (p2.x() - p3.x()) * (p1.y() - p3.y());
} }
static bool IsPointInTriangle(Point &pt, Point &p1, Point &p2, Point &p3) static bool IsPointInTriangle(const Point &pt, const Point &p1, const Point &p2, const Point &p3)
{ {
float d1 = sign(pt, p1, p2); float d1 = sign(pt, p1, p2);
float d2 = sign(pt, p2, p3); float d2 = sign(pt, p2, p3);