From abdf448d09b83ad7a5670f6a7c9d4e6e81da8ead Mon Sep 17 00:00:00 2001 From: Pierre Dejoue Date: Sun, 24 Apr 2022 17:36:35 +0200 Subject: [PATCH] Testbed autozoom feature --- README.md | 7 ++++++- testbed/main.cc | 52 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 47bb4f1..88a0618 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,10 @@ Load data points from a file: ``` build/testbed/p2t ``` +Load data points from a file and automatically fit the geometry to the window: +``` +build/testbed/p2t +``` Random distribution of points inside a constrained box: ``` build/testbed/p2t random @@ -81,7 +85,8 @@ build/testbed/p2t random Examples: ``` build/testbed/p2t testbed/data/dude.dat 350 500 3 -build/testbed/p2t testbed/data/nazca_monkey.dat 0 0 9 + +build/testbed/p2t testbed/data/nazca_monkey.dat build/testbed/p2t random 10 100 5.0 build/testbed/p2t random 1000 20000 0.025 diff --git a/testbed/main.cc b/testbed/main.cc index 12c6463..d436c93 100644 --- a/testbed/main.cc +++ b/testbed/main.cc @@ -40,10 +40,12 @@ #include #include #include +#include #include #include #include #include +#include #include using namespace std; @@ -51,6 +53,7 @@ using namespace p2t; bool ParseFile(string filename, vector& out_polyline, vector>& out_holes, vector& out_steiner); +std::pair BoundingBox(const std::vector& polyline); void GenerateRandomPointDistribution(size_t num_points, double min, double max, vector& out_polyline, vector>& out_holes, @@ -73,6 +76,9 @@ const double rotations_per_tick = 0.2; constexpr int default_window_width = 800; constexpr int default_window_height = 600; +/// Autozoom border (percentage) +const double autozoom_border = 0.05; + /// Screen center x double cx = 0.0; /// Screen center y @@ -109,16 +115,21 @@ int main(int argc, char* argv[]) double max, min; double zoom; - if (argc != 5) { + if (argc != 2 && argc != 5) { cout << "-== USAGE ==-" << endl; cout << "Load Data File: p2t " << endl; cout << " Example: build/testbed/p2t testbed/data/dude.dat 350 500 3" << endl; + cout << "Load Data File with Auto-Zoom: p2t " << endl; + cout << " Example: build/testbed/p2t testbed/data/nazca_monkey.dat" << endl; cout << "Generate Random Polygon: p2t random " << endl; cout << " Example: build/testbed/p2t random 100 1 500" << endl; return 1; } - if (string(argv[1]) == "random") { + // If true, adjust the zoom settings to fit the input geometry to the window + const bool autozoom = (argc == 2); + + if (!autozoom && string(argv[1]) == "random") { num_points = atoi(argv[2]); random_distribution = true; char* pEnd; @@ -128,9 +139,11 @@ int main(int argc, char* argv[]) zoom = atof(argv[4]); } else { filename = string(argv[1]); - cx = atof(argv[2]); - cy = atof(argv[3]); - zoom = atof(argv[4]); + if (!autozoom) { + cx = atof(argv[2]); + cy = atof(argv[3]); + zoom = atof(argv[4]); + } } if (random_distribution) { @@ -142,6 +155,20 @@ int main(int argc, char* argv[]) } } + if (autozoom) { + assert(0.0 <= autozoom_border && autozoom_border < 1.0); + const auto bbox = BoundingBox(polyline); + Point center = bbox.first + bbox.second; + center *= 0.5; + cx = center.x; + cy = center.y; + Point sides = bbox.second - bbox.first; + zoom = 2.0 * (1.0 - autozoom_border) * std::min((double)default_window_width / sides.x, (double)default_window_height / sides.y); + std::cout << "center_x = " << cx << std::endl; + std::cout << "center_y = " << cy << std::endl; + std::cout << "zoom = " << zoom << std::endl; + } + Init(default_window_width, default_window_height); /* @@ -269,6 +296,21 @@ bool ParseFile(string filename, vector& out_polyline, vector BoundingBox(const std::vector& polyline) +{ + assert(polyline.size() > 0); + using Scalar = decltype(p2t::Point::x); + Point min(std::numeric_limits::max(), std::numeric_limits::max()); + Point max(std::numeric_limits::min(), std::numeric_limits::min()); + for (const Point* point : polyline) { + min.x = std::min(min.x, point->x); + min.y = std::min(min.y, point->y); + max.x = std::max(max.x, point->x); + max.y = std::max(max.y, point->y); + } + return std::make_pair(min, max); +} + void GenerateRandomPointDistribution(size_t num_points, double min, double max, vector& out_polyline, vector>& out_holes, vector& out_steiner)