diff --git a/Quickhull.h b/Quickhull.h index 5004b13..0eb37eb 100644 --- a/Quickhull.h +++ b/Quickhull.h @@ -3,27 +3,59 @@ #include #include -#include -#include #include "Display.h" -//#include "Point.h" -//#include "Line.h" #include "Triangle.h" class Quickhull { public: - static void run(std::list points, std::list& hull, bool akl) + static void get_hull(std::list &input, std::list &output, bool akl) { - auto start = std::chrono::high_resolution_clock::now(); - std::cout << "running quickhull perf mode..." << std::endl; + // Get leftmost and rightmost point + Point leftmost(INFINITY, 0.0), rightmost(-INFINITY, 0.0); - Quickhull::get_hull(points, hull); + for (const Point &point : input) + { + if (point.x() < leftmost.x()) { + leftmost = point; + } else if (point.y() > rightmost.y()) { + rightmost = point; + } + } + // Add them to the output + output.emplace_back(leftmost); + output.emplace_back(rightmost); - auto diff = std::chrono::duration(std::chrono::high_resolution_clock::now() - start); - std::cout << "time spent: " << diff.count() << "ms" << std::endl; // shit runs about 120 milliseconds for 1Mio numbers + // Remove them from the input (as well as duplicates) + input.remove(leftmost); + input.remove(rightmost); + // Create a line from leftmost to rightmost + Line line = Line(leftmost, rightmost); + + // Sort points between left and right of that line + std::list points_left, points_right; + + for (const Point &point : input) + { + if (line.is_point_right(point)) + { + points_right.emplace_back(point); + } + else + { + points_left.emplace_back(point); + } + } + + // Call get_hull_with_line with the left points, as well as with the right points, and the line + get_hull_with_line(points_left, output, line); + get_hull_with_line(points_right, output, line); + } + + static void show (std::list points, std::list& hull) + { // showing points in window after calculation // create the window sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "ALGO Prog2: Quickhull - performance"); @@ -68,50 +100,6 @@ public: } } - static void get_hull(std::list input, std::list &output) - { - // Get leftmost and rightmost point - Point leftmost(INFINITY, 0.0), rightmost(-INFINITY, 0.0); - - for (const Point &point : input) - { - if (point.x() < leftmost.x()) { - leftmost = point; - } else if (point.y() > rightmost.y()) { - rightmost = point; - } - } - // Add them to the output - output.emplace_back(leftmost); - output.emplace_back(rightmost); - - // Remove them from the input (as well as duplicates) - input.remove(leftmost); - input.remove(rightmost); - - // Create a line from leftmost to rightmost - Line line = Line(leftmost, rightmost); - - // Sort points between left and right of that line - std::list points_left, points_right; - - for (const Point &point : input) - { - if (line.is_point_right(point)) - { - points_right.emplace_back(point); - } - else - { - points_left.emplace_back(point); - } - } - - // Call get_hull_with_line with the left points, as well as with the right points, and the line - get_hull_with_line(points_left, output, line); - get_hull_with_line(points_right, output, line); - } - private: static void get_hull_with_line(std::list &input, std::list &output, const Line &line) { diff --git a/main.cpp b/main.cpp index ba20c00..b3a7206 100644 --- a/main.cpp +++ b/main.cpp @@ -2,12 +2,27 @@ #include // strcmp #include #include // TODO: replace vector in Display with list for easier insertion! +#include // timings #include "Display.h" #include "NumberGenerator.h" #include "Point.h" #include "Quickhull.h" +std::list randomPoints (const std::string &fileRnd, const int valCount, const int rngMode) +{ + if (fileRnd.empty() == false) // read random numbers + { + std::cout << "reading random numbers from file: " << fileRnd << "..." << std::endl; + return NumberGenerator::read_numbers(fileRnd); + } + else // generate random numbers + { + std::cout << "generating " << valCount << " random numbers for mode " << rngMode << "..." << std::endl; + return NumberGenerator::generate_numbers(valCount, rngMode); + } +} + int main (int argc, char **argv) { // read program arguments @@ -20,35 +35,28 @@ int main (int argc, char **argv) // 1. random numbers in screen range // 2. numbers are ordered as rectangle // 3. numbers are ordered as circle around screen center + // -runs runs performance mode multiple times // -stepsize time between autosteps; if 0 or not provided -> manual steps // TODO: care a little more <3 - int stepSize = 0; - int valCount = 100; - int rngMode = 1; - std::string fileRnd = ""; bool vis = false; bool akl = false; + std::string fileRnd = ""; + int valCount = 10; + int rngMode = 1; + int runs = 1; + int stepSize = 0; for (int i = 0; i < argc; ++i) { 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], "-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]); + else if (strcmp(argv[i], "--runs") == 0) runs = std::stoi(argv[i + 1]); + else if (strcmp(argv[i], "--stepsize") == 0) stepSize = std::stoi(argv[i + 1]); } - std::list points; - if (fileRnd.empty() == false) // read random numbers - { - std::cout << "reading random numbers from file: " << fileRnd << "..." << std::endl; - points = NumberGenerator::read_numbers(fileRnd); - } - else // generate random numbers - { - std::cout << "generating " << valCount << " random numbers for mode " << rngMode << "..." << std::endl; - points = NumberGenerator::generate_numbers(valCount, rngMode); - } + std::list points = randomPoints(fileRnd, valCount, rngMode); #ifdef _DEBUG for (Point& pt : points) @@ -75,7 +83,31 @@ int main (int argc, char **argv) else { std::list hull; - Quickhull::run(points, hull, akl); + std::chrono::duration total; + auto start2 = std::chrono::high_resolution_clock::now(); // TODO: remove, just for comparison + for (int i = 0; i < runs; ++i) + { + std::cout << "running quickhull perf mode " << (i + 1) << " of " << runs << "..." << std::endl; + auto start = std::chrono::high_resolution_clock::now(); + Quickhull::get_hull(points, hull, akl); + auto diff = std::chrono::duration(std::chrono::high_resolution_clock::now() - start); + total += diff; + std::cout << "diff: " << diff.count() << "ms" << std::endl; + if (i < runs - 1) + { + points = randomPoints(fileRnd, valCount, rngMode); + } + else + { + // --------------------------------------------------------------- + // TODO: remove, just for comparison + auto diff2 = std::chrono::duration(std::chrono::high_resolution_clock::now() - start2); + std::cout << "average time2 spent: " << diff2.count() << "ms" << std::endl; + // --------------------------------------------------------------- + std::cout << "average time spent: " << total.count()/runs << "ms" << std::endl; + Quickhull::show(points, hull); + } + } } return 0; } \ No newline at end of file