#include // cin, cout #include // ifstream #include // srand, rand #include // time #include // strcmp #include // TODO: or use arrays for maximum performance? #include // TODO: replace vector with list for easier insertion! #include "Display.h" #include "NumberGenerator.h" #include "Point.h" #include "Quickhull.h" int main (int argc, char **argv) { // read program arguments // -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 read random numbers from file // -rngCount generates count random float values // -rngMode 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 time between autosteps; if 0 or not provided -> manual steps // TODO: care a little more <3 int stepSize = 0; int valCount = 1000000; int rngMode = 1; std::string fileRnd = ""; bool vis = false; bool akl = false; 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]); } std::list points; if (fileRnd.empty()) // generate random numbers { std::cout << "generating " << valCount << " random numbers for mode " << rngMode << "..." << std::endl; if (rngMode == 1) { points = NumberGenerator::get_random_numbers(valCount); } 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 { std::cout << "reading random numbers from file: " << fileRnd << "..." << std::endl; std::ifstream in(fileRnd.c_str()); if (in.is_open()) { std::string line; std::getline(in, line); // get first line for explizit valueCount valCount = std::stoi(line); float x = 0; float y = 0; for (int i = 0; i < valCount; ++i) { getline(in, line); //getline(in, line, ','); // could also be used slightly different but includes newlines :/ size_t pos = line.find(','); if (pos != std::string::npos) { x = std::stof(line.substr(0, pos)); y = std::stof(line.substr(pos + 1)); points.push_back(Point(x, y)); } else { throw "invalid format!"; } } } } #ifdef _DEBUG /*for (Point& pt : points) { std::cout << "pt: " << pt.x() << ", " << pt.y() << std::endl; }*/ #endif // TEST to check SFML coordinate system //points.push_back(Point(0, 0)); if (vis) { // TODO: replace implementation to use list instead of vector std::vector v_points; for (Point const& pt : points) { v_points.push_back(pt); } Display display(v_points, stepSize, akl); display.show(); } else { std::list hull; Quickhull::run(points, hull, akl); } return 0; }