merged performance into main -> now used vor vis and perf mode; adding param akl for heuristic

This commit is contained in:
incredibleLeitman 2020-11-30 15:43:42 +01:00
parent bda1158e7f
commit 1c73b14f24
5 changed files with 115 additions and 68 deletions

View File

@ -7,7 +7,7 @@
#include "Point.h" #include "Point.h"
#include "Utility.h" #include "Utility.h"
Display::Display (const std::vector<Point> &pts, int stepSize) : m_stepSize(stepSize) Display::Display (const std::vector<Point> &pts, int stepSize, bool akl) : m_stepSize(stepSize), m_useAkl(akl)
{ {
if (!m_font.loadFromFile("Resources/LiberationSans-Regular.ttf")) if (!m_font.loadFromFile("Resources/LiberationSans-Regular.ttf"))
{ {
@ -100,9 +100,6 @@ void Display::show()
void Display::update () void Display::update ()
{ {
// TODO: maybe include AklToussaint heuristic first?
// https://en.wikipedia.org/wiki/Convex_hull_algorithms#Akl%E2%80%93Toussaint_heuristic
unsigned int curStep = (m_step > 5) ? ((m_step - 2) % 4 + 2) : (m_step % 6); // skip init and first step after first run 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) if (m_stepSize == 0 && curStep > 0)
{ {
@ -117,8 +114,7 @@ void Display::update ()
m_textStatus.setString(text + "select min - max x coordinates..."); m_textStatus.setString(text + "select min - max x coordinates...");
// if use AklToussaint heuristic // if use AklToussaint heuristic
bool useAkl = false; if (m_useAkl)
if (useAkl)
{ {
sf::Vector2f topLeft(WIDTH, HEIGHT); sf::Vector2f topLeft(WIDTH, HEIGHT);
sf::Vector2f topRight(0, HEIGHT); sf::Vector2f topRight(0, HEIGHT);

View File

@ -20,6 +20,8 @@ class Display
{ {
private: private:
int m_stepSize; int m_stepSize;
bool m_useAkl;
sf::Font m_font; sf::Font m_font;
sf::Text m_textStatus; sf::Text m_textStatus;
@ -46,7 +48,7 @@ private:
void render(sf::RenderWindow &); void render(sf::RenderWindow &);
public: public:
Display(const std::vector<Point> &, int stepSize = 0); Display(const std::vector<Point> &, int stepSize = 0, bool akl = false);
void show(); void show();
}; };

View File

@ -5,11 +5,6 @@
class NumberGenerator class NumberGenerator
{ {
private:
static const int OFFSET = 0;
static const int WIDTH = 700;
static const int HEIGHT = 700;
public: public:
static std::list<Point> get_random_numbers(int valCount) static std::list<Point> get_random_numbers(int valCount)
{ {
@ -35,7 +30,7 @@ public:
{ {
std::list<Point> points; std::list<Point> points;
float diff = (2.f * HEIGHT / valCount); float diff = (2.f * HEIGHT/valCount);
float x = 0; float x = 0;
float y = 0; float y = 0;
@ -54,7 +49,7 @@ public:
{ {
std::list<Point> points; std::list<Point> points;
float rad = HEIGHT / 2; //8.0f; float rad = HEIGHT/2;
float deg = (float)(2 * 3.14159 / valCount); float deg = (float)(2 * 3.14159 / valCount);
float x = 0; float x = 0;

View File

@ -3,16 +3,72 @@
#include <list> #include <list>
#include <limits.h> #include <limits.h>
#include <chrono>
#include <iostream>
#include "Display.h"
#include "Point.h" #include "Point.h"
#include "Line.h" //#include "Line.h"
#include "Triangle.h" #include "Triangle.h"
class Quickhull class Quickhull
{ {
public: public:
static void get_hull(std::list<Point> input, std::list<Point> &output) static void run(std::list<Point> points, std::list<Point>& hull, bool akl)
{
auto start = std::chrono::high_resolution_clock::now();
std::cout << "running quickhull perf mode..." << std::endl;
Quickhull::get_hull(points, hull);
auto diff = std::chrono::duration<double, std::milli>(std::chrono::high_resolution_clock::now() - start);
std::cout << "time spent: " << diff.count() << "ms" << std::endl; // shit runs about 120 milliseconds for 1Mio numbers
// showing points in window after calculation
// create the window
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "ALGO Prog2: Quickhull - performance");
sf::CircleShape normal_p(2);
normal_p.setFillColor(sf::Color(250, 250, 250));
sf::CircleShape hull_p(2);
hull_p.setFillColor(sf::Color(250, 100, 50));
// run the program as long as the window is open
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
}
// clear the window with black color
window.clear(sf::Color::Black);
// Draw all points
for (const Point& point : points)
{
normal_p.setPosition(point.x(), point.y());
window.draw(normal_p);
}
// Draw hull points
for (const Point& point : hull)
{
hull_p.setPosition(point.x(), point.y());
window.draw(hull_p);
}
// end the current frame
window.display();
}
}
static void get_hull(std::list<Point> input, std::list<Point> &output)
{ {
// Get leftmost and rightmost point // Get leftmost and rightmost point
Point leftmost(INFINITY, 0.0), rightmost(-INFINITY, 0.0); Point leftmost(INFINITY, 0.0), rightmost(-INFINITY, 0.0);

100
main.cpp
View File

@ -4,74 +4,62 @@
#include <ctime> // time #include <ctime> // time
#include <cstring> // strcmp #include <cstring> // strcmp
#include <vector> // TODO: or use arrays for maximum performance? #include <vector> // TODO: or use arrays for maximum performance?
#include <list> // TODO: replace vector with list for easier insertion!
#include "Display.h" #include "Display.h"
#include "NumberGenerator.h"
#include "Point.h" #include "Point.h"
#include "Quickhull.h"
// TODOs:
// - use SFML vec2 instead of Point class
// - calc min and max points for x, y
// *) just a loop and save/override points -> maybe in Data Block?
// *) std::minmax_element for x, y -> not saving just temp draw
// https://en.cppreference.com/w/cpp/algorithm/minmax_element
// - actual algorithm :p
// - architecture:
// # vis in own thread, calls "lib" functions?
// # seperate implementation for vis and perf?
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
// read program arguments // read program arguments
// -v mode with enabled visualization // -v mode with enabled visualization
// -akl using Akl-Toussaint heuristic beforehand
// https://en.wikipedia.org/wiki/Convex_hull_algorithms#Akl%E2%80%93Toussaint_heuristic
// -f <filename> read random numbers from file // -f <filename> read random numbers from file
// -rngCount <count> generates count random float values
// -rngMode <mode> if generating float values this specifies the mode:
// 1. random numbers in screen range
// 2. numbers are ordered as rectangle
// 3. numbers are ordered as circle around screen center
// -stepsize <size> time between autosteps; if 0 or not provided -> manual steps // -stepsize <size> time between autosteps; if 0 or not provided -> manual steps
// TODO: care a little more <3 // TODO: care a little more <3
int stepSize = 0; int stepSize = 0;
int valCount = 1000000;
int rngMode = 1;
std::string fileRnd = ""; std::string fileRnd = "";
bool vis = false; bool vis = false;
bool akl = false;
for (int i = 0; i < argc; ++i) for (int i = 0; i < argc; ++i)
{ {
if (strcmp(argv[i], "-v") == 0) vis = true; if (strcmp(argv[i], "-v") == 0) vis = true;
else if (strcmp(argv[i], "-akl") == 0) akl = true;
else if (strcmp(argv[i], "-stepsize") == 0) stepSize = std::stoi(argv[i + 1]); else if (strcmp(argv[i], "-stepsize") == 0) stepSize = std::stoi(argv[i + 1]);
else if (strcmp(argv[i], "-f") == 0) fileRnd = argv[i + 1]; else if (strcmp(argv[i], "-f") == 0) fileRnd = argv[i + 1];
else if (strcmp(argv[i], "-rngCount") == 0) valCount = std::stoi(argv[i + 1]);
else if (strcmp(argv[i], "-rngMode") == 0) rngMode = std::stoi(argv[i + 1]);
} }
int valCount = 10; std::list<Point> points;
std::vector<Point> points;
if (fileRnd.empty()) // generate random numbers if (fileRnd.empty()) // generate random numbers
{ {
std::cout << "generating random numbers..." << std::endl; std::cout << "generating " << valCount << " random numbers for mode " << rngMode << "..." << std::endl;
//srand(static_cast <unsigned> (time(0))); if (rngMode == 1)
srand(static_cast <unsigned> (0)); // fixed seed for testing
// 2) rectangle
//float diff = (2.f * HEIGHT / valCount);
// 3) circle
//float rad = HEIGHT / 2; //8.0f;
//float deg = (float)(2 * 3.14159 / valCount);
float x = 0;
float y = 0;
for (int i = 0; i < valCount; ++i)
{ {
// 1) random generation points = NumberGenerator::get_random_numbers(valCount);
//x = OFFSET + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (WIDTH - OFFSET)));
//y = OFFSET + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (HEIGHT - OFFSET)));
x = OFFSET + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (WIDTH - 2*OFFSET)));
y = OFFSET + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (HEIGHT - 2*OFFSET)));
// 2) rectangle
//x = (i%2 == 0) ? OFFSET : WIDTH - OFFSET;
//y = diff/2 + (i/2) * diff;
// 3) position in circle around center, x/y plane
//x = WIDTH/2 + rad * cosf(i * deg);
//y = HEIGHT/2 + rad * sinf(i * deg);
points.push_back(Point(x, y));
} }
else if (rngMode == 2)
{
points = NumberGenerator::get_rectangle_numbers(valCount);
}
else if (rngMode == 3)
{
points = NumberGenerator::get_circle_numbers(valCount);
}
else throw "unspecified rng Mode"; // TODO: could handle in parse args
} }
// TODO: move into NumberGenerator?
else // read random numbers else // read random numbers
{ {
std::cout << "reading random numbers from file: " << fileRnd << "..." << std::endl; std::cout << "reading random numbers from file: " << fileRnd << "..." << std::endl;
@ -102,22 +90,32 @@ int main (int argc, char **argv)
} }
} }
// debug print points #ifdef _DEBUG
for (Point& pt : points) /*for (Point& pt : points)
{ {
std::cout << "pt: " << pt.x() << ", " << pt.y() << std::endl; std::cout << "pt: " << pt.x() << ", " << pt.y() << std::endl;
} }*/
#endif
// TEST to check SFML coordinate system
//points.push_back(Point(0, 0));
if (vis) if (vis)
{ {
// TEST to check SFML coordinate system // TODO: replace implementation to use list instead of vector
//points.push_back(Point(0, 0)); std::vector<Point> v_points;
for (Point const& pt : points)
{
v_points.push_back(pt);
}
Display display(points, stepSize); Display display(v_points, stepSize, akl);
display.show(); display.show();
} }
else
std::cout << "any key to exit..."; {
std::cin.get(); std::list<Point> hull;
Quickhull::run(points, hull, akl);
}
return 0; return 0;
} }