From 52213825dec606c05000300676c94753af4ed736 Mon Sep 17 00:00:00 2001 From: incredibleLeitman Date: Sun, 29 Nov 2020 04:04:25 +0100 Subject: [PATCH] using line class, playing with convex shape element --- Display.cpp | 138 ++++++++++++++++++++++++++++++++++++++++++---------- Display.h | 11 ++++- 2 files changed, 122 insertions(+), 27 deletions(-) diff --git a/Display.cpp b/Display.cpp index c600b1c..7be0b76 100644 --- a/Display.cpp +++ b/Display.cpp @@ -4,12 +4,13 @@ #include #include "Display.h" +//#include "Line.h" #include "Point.h" #include "Utility.h" Display::Display (const std::vector &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(); diff --git a/Display.h b/Display.h index 76b53bd..95f80b6 100644 --- a/Display.h +++ b/Display.h @@ -6,7 +6,11 @@ // windows - manual dl from https://www.sfml-dev.org/download.php #include -class Point; + +#include "Line.h" + +//class Point; +//class Line; #define OFFSET 10.f #define WIDTH 800 @@ -26,6 +30,11 @@ private: //std::vector m_hull; sf::VertexArray m_hull; + sf::ConvexShape m_convex; + + //std::map > m_pointsForLine; + std::vector m_lines; + Line *m_curLine = nullptr; unsigned int m_step = 0; void update();