Compare commits

...

2 Commits

3 changed files with 124 additions and 29 deletions

View File

@ -4,12 +4,13 @@
#include <thread>
#include "Display.h"
//#include "Line.h"
#include "Point.h"
#include "Utility.h"
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;
}
@ -146,12 +147,13 @@ void Display::update ()
/* TODO: use a convex shape? Or build from vertices in render?
sf::ConvexShape convex;
convex.setPointCount(5);
convex.setPointCount(4);
convex.setPoint(0, topLeft);
convex.setPoint(0, topRight);
convex.setPoint(0, botRight);
convex.setPoint(0, botLeft);*/
convex.setPoint(1, topRight);
convex.setPoint(2, botRight);
convex.setPoint(3, botLeft);*/
//m_ hull as VertexArray
//m_hull.setPrimitiveType(sf::Lines);
m_hull.setPrimitiveType(sf::LineStrip);
m_hull.append(sf::Vertex(topLeft, sf::Color::Blue));
@ -169,32 +171,70 @@ void Display::update ()
{
sf::Vector2f pos = pt.getPosition();
float x = pos.x;
float y = pos.y;
//float y = pos.y;
if (x < left.x) left = pos;
if (x > right.x) right = pos;
}
//m_ hull as VertexArray
//m_hull.setPrimitiveType(sf::Lines);
m_hull.setPrimitiveType(sf::LineStrip);
m_hull.append(sf::Vertex(left, 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)
{
// second step: split board and find furthest point
m_textStatus.setString(text + "split board and find furthest point...");
// second step: split board
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)
{
pt.setFillColor(sign(
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) > 0 ? sf::Color::Red : sf::Color::Green);
//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_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)
{
// get line with more than one point -> or use m_curLine
// calc furthest point
// create new lines
// third step: draw triangle, remove inner points
m_textStatus.setString(text + "find furthest point and draw triangle...");
@ -202,11 +242,7 @@ void Display::update ()
float maxDistance = 0;
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)
{
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;
}
*/
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)
{
@ -225,14 +271,47 @@ void Display::update ()
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[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)
{
// fourth step: 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)
{
@ -253,14 +332,16 @@ void Display::render (sf::RenderWindow &window)
{
window.clear(sf::Color::White);
// always print remaining points
/*size_t points = m_points.size();
for (size_t i = 0; i < points; ++i)
// draw already calculated hull
//if (step >= 1)
{
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();
for (size_t i = 0; i < points; ++i)
{
@ -268,13 +349,18 @@ void Display::render (sf::RenderWindow &window)
window.draw(m_labels[i]);
}
// draw already calculated hull
//if (step >= 1)
// draw line the algorithm is currently working on
if (m_curLine != nullptr)
{
//window.draw(&m_hull[0], m_hull.size(), sf::Lines);
window.draw(&m_hull[0], m_hull.getVertexCount(), m_hull.getPrimitiveType());
sf::Vertex line[] =
{
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.display();

View File

@ -6,7 +6,11 @@
// windows - manual dl from https://www.sfml-dev.org/download.php
#include <SFML/Graphics.hpp>
class Point;
#include "Line.h"
//class Point;
//class Line;
#define OFFSET 10.f
#define WIDTH 800
@ -26,6 +30,11 @@ private:
//std::vector<sf::Vertex> 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;
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);
}
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());
}
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 d2 = sign(pt, p2, p3);