From d58645bdc775342e1052b0d2ae798e149679bd8b Mon Sep 17 00:00:00 2001 From: kallaballa Date: Tue, 21 Sep 2021 14:16:23 +0200 Subject: [PATCH] improved on the looping issue --- data/handcrafted/5M/golden.wkt | 2 +- data/handcrafted/5Z/golden.wkt | 3 +- data/handcrafted/5r/golden.wkt | 2 +- data/handcrafted/aY/golden.wkt | 2 +- data/handcrafted/crossing/golden.wkt | 2 +- src/algo/search_start.hpp | 15 -------- src/algo/select_next.hpp | 54 ++++++++++++++++++++-------- src/algo/slide.hpp | 2 +- src/geometry.hpp | 23 ++++++++++++ 9 files changed, 69 insertions(+), 36 deletions(-) diff --git a/data/handcrafted/5M/golden.wkt b/data/handcrafted/5M/golden.wkt index 3437033..cfd5876 100644 --- a/data/handcrafted/5M/golden.wkt +++ b/data/handcrafted/5M/golden.wkt @@ -1 +1 @@ -POLYGON((872 -1472,1152 -1201,1152 -1073,1152 -722,1152 -594,960 -398.431226766,960 -192,1024 -192,1024 -64,1024 5.55111512313e-17,1024 19.1142857143,1152 143,1152 271,1152 622,1152 750,883 1024,832 1024,832 1152,1024 1152,1024 1280,1024 1344,1024 1472,512 1472,256 1472,-256 1472,-256 1344,-256 1280,-256 1237,-256 1280,-256 1237,-256 1280,-256 1344,-256 1472,-832 1472,-1024 1472,-1600 1472,-1600 1344,-1600 768,-1600 640,-1494 640,-1408 640,-1408 448,-1536 448,-1664 448,-1664 320,-1664 128,-1664 0,-1600 -37.1428571429,-1600 -576,-1600 -704,-1494 -704,-1472 -704,-1472 -896,-1536 -896,-1664 -896,-1664 -1024,-1664 -1216,-1664 -1344,-1552 -1409,-1339 -1472,-984 -1472,-949 -1472,-594 -1472,-314 -1201,-312.537317125 -1198.08027079,-240 -1344,-128 -1409,85 -1472,440 -1472,517 -1472,872 -1472)) +POLYGON((872 -1472,1152 -1201,1152 -1073,1152 -722,1152 -594,960 -398.431226766,960 -192,1024 -192,1024 -64,1024 5.55111512313e-17,1024 19.1142857143,1152 143,1152 271,1152 622,1152 750,883 1024,832 1024,832 1152,1024 1152,1024 1280,1024 1344,1024 1472,512 1472,256 1472,-256 1472,-832 1472,-1024 1472,-1600 1472,-1600 1344,-1600 768,-1600 640,-1494 640,-1408 640,-1408 448,-1536 448,-1664 448,-1664 320,-1664 128,-1664 0,-1600 -37.1428571429,-1600 -576,-1600 -704,-1494 -704,-1472 -704,-1472 -896,-1536 -896,-1664 -896,-1664 -1024,-1664 -1216,-1664 -1344,-1552 -1409,-1339 -1472,-984 -1472,-949 -1472,-594 -1472,-314 -1201,-312.537317125 -1198.08027079,-240 -1344,-128 -1409,85 -1472,440 -1472,517 -1472,872 -1472)) diff --git a/data/handcrafted/5Z/golden.wkt b/data/handcrafted/5Z/golden.wkt index 36218bf..d79c634 100644 --- a/data/handcrafted/5Z/golden.wkt +++ b/data/handcrafted/5Z/golden.wkt @@ -1,2 +1 @@ -POLYGON((808 -1472,1088 -1201,1088 -881,1088 -722,1088 -402,881.832116788 -192,960 -192,960 -60.0170212766,1152 200,1152 271,1152 679,1152 750,885.507540871 1021.44585056,1024 1209,1024 1280,1024 1401,1024 1472,256 1472,-256 1472,-1024 1472,-1024 1152,-1024 768,-1024 448,-1088 448,-1088 128,-1088 -192,-976 -257,-960 -261.732394366,-960 -633,-960 -704,-854 -704,-841.113118617 -704,-1024 -953,-1024 -1024,-1024 -1273,-1024 -1344,-912 -1409,-699 -1472,-344 -1472,453 -1472,808 -1472)) -POLYGON((-738 513,-790 448,-683.09897879 448,-589.084838963 576,-603 576,-738 513)) +POLYGON((808 -1472,1088 -1201,1088 -881,1088 -722,1088 -402,881.832116788 -192,960 -192,960 -60.0170212766,1152 200,1152 271,1152 679,1152 750,885.507540871 1021.44585056,1024 1209,1024 1280,1024 1401,1024 1472,256 1472,-256 1472,-1024 1472,-1024 1152,-1024 768,-1024 448,-960 448,-918 448,-896 448,-790 448,-738 513,-603 576,-589.084838963 576,-683.09897879 448,-790 448,-896 448,-918 448,-960 448,-1024 448,-1088 448,-1088 128,-1088 -192,-976 -257,-960 -261.732394366,-960 -633,-960 -704,-854 -704,-841.113118617 -704,-1024 -953,-1024 -1024,-1024 -1273,-1024 -1344,-912 -1409,-699 -1472,-344 -1472,453 -1472,808 -1472)) diff --git a/data/handcrafted/5r/golden.wkt b/data/handcrafted/5r/golden.wkt index 04134d7..826b968 100644 --- a/data/handcrafted/5r/golden.wkt +++ b/data/handcrafted/5r/golden.wkt @@ -1 +1 @@ -POLYGON((1768 0,2048 271,2048 399,2048 750,2048 878,1870.29556407 1059.00749236,2048 1231,2048 1359,2048 1710,2048 1838,1779 2112,1728 2112,1728 2240,1920 2240,1920 2368,1920 2432,1920 2560,1344 2560,1152 2560,576 2560,576 2432,576 1856,576 1728,682 1728,733.891428571 1728,682 1728,733.891428571 1728,682 1728,576 1728,682 1728,576 1728,384 1728,256 1728,256 1472,256 1024,256 768,362 768,558 768,664 768,704 792.150943396,704 751,577 576,521 576,452 640,448 704,320 704,192 704,192 448,192 384,192 128,304 63,517 0,819 0,872 0,1029 0,1174 0,1384 0,1413 0,1768 0)) +POLYGON((1768 0,2048 271,2048 399,2048 750,2048 878,1870.29556407 1059.00749236,2048 1231,2048 1359,2048 1710,2048 1838,1779 2112,1728 2112,1728 2240,1920 2240,1920 2368,1920 2432,1920 2560,1344 2560,1152 2560,576 2560,576 2432,576 1856,576 1728,384 1728,256 1728,256 1472,256 1024,256 768,362 768,558 768,664 768,704 792.150943396,704 751,577 576,521 576,452 640,448 704,320 704,192 704,192 448,192 384,192 128,304 63,517 0,819 0,872 0,1029 0,1174 0,1384 0,1413 0,1768 0)) diff --git a/data/handcrafted/aY/golden.wkt b/data/handcrafted/aY/golden.wkt index f98fb7f..2243bbd 100644 --- a/data/handcrafted/aY/golden.wkt +++ b/data/handcrafted/aY/golden.wkt @@ -1 +1 @@ -POLYGON((1600 -1472,1600 -1344,1600 -1216,1466 -1216,1408 -1123.35746606,1408 -834,1408 -706,1375.10614525 -706,1408 -614,1408 -486,1172 -256,1130.00566572 -256,1049.86968839 -128,1216 -128,1216 0,1216 128,1024 128,1024 510,1024 638,991.106145251 638,1024 730,1024 858,788 1088,475 1088,212 1088,-101 1088,-286 1024,-384 960,-384 832,-384 768,-384 640,-256 640,-216 640,-192 640,-216 640,-192 640,-216 640,-448 472,-448 344,-448 173,-448 45,-388.729703801 -5.01834752368,-566.450104788 -284.177333548,-670 -320,-768 -384,-768 -512,-768 -576,-768 -704,-640 -704,-600 -704,-587.046511628 -704,-600 -704,-587.046511628 -704,-600 -704,-587.046511628 -704,-600 -704,-832 -872,-832 -1000,-832 -1171,-832 -1299,-627 -1472,-346 -1472,-185 -1472,-128 -1472,96 -1472,211 -1472,256 -1472,314 -1472,492 -1472,698 -1472,710 -1472,717 -1472,998 -1472,1094 -1472,1216 -1472,1600 -1472)) +POLYGON((1600 -1472,1600 -1344,1600 -1216,1466 -1216,1408 -1123.35746606,1408 -834,1408 -706,1375.10614525 -706,1408 -614,1408 -486,1172 -256,1130.00566572 -256,1049.86968839 -128,1216 -128,1216 0,1216 128,1024 128,1024 510,1024 638,991.106145251 638,1024 730,1024 858,788 1088,475 1088,212 1088,-101 1088,-286 1024,-384 960,-384 832,-384 768,-384 640,-256 640,-216 640,-192 640,-216 640,-448 472,-448 344,-448 173,-448 45,-388.729703801 -5.01834752368,-566.450104788 -284.177333548,-670 -320,-768 -384,-768 -512,-768 -576,-768 -704,-640 -704,-600 -704,-587.046511628 -704,-600 -704,-832 -872,-832 -1000,-832 -1171,-832 -1299,-627 -1472,-346 -1472,-185 -1472,-128 -1472,96 -1472,211 -1472,256 -1472,314 -1472,492 -1472,698 -1472,710 -1472,717 -1472,998 -1472,1094 -1472,1216 -1472,1600 -1472)) diff --git a/data/handcrafted/crossing/golden.wkt b/data/handcrafted/crossing/golden.wkt index 19c0dba..908b258 100644 --- a/data/handcrafted/crossing/golden.wkt +++ b/data/handcrafted/crossing/golden.wkt @@ -1 +1 @@ -POLYGON((60 30,70 50,70 60,50 80,40 80,30 80,10 60,10 50,20 30,30 30,40 30,40 40,40 50,30 50,40 50,30 50,40 50,40 60,40 50,40 60,40 50,50 50,40 50,50 50,40 50,40 40,40 30,40 40,40 50,40 40,40 50,30 50,40 50,30 50,40 50,40 60,40 50,40 60,40 50,50 50,40 50,50 50,40 50,40 40,40 30,50 30,60 30)) +POLYGON((60 30,70 50,70 60,50 80,40 80,30 80,10 60,10 50,20 30,30 30,40 30,40 40,40 50,30 50,40 50,40 60,40 50,50 50,40 50,40 40,40 30,50 30,60 30)) diff --git a/src/algo/search_start.hpp b/src/algo/search_start.hpp index 3165ab9..8dfd9a5 100644 --- a/src/algo/search_start.hpp +++ b/src/algo/search_start.hpp @@ -6,21 +6,6 @@ namespace libnfporb { -/** - * @brief Checks if a point exists in a NFP - * @param pt The point to look for - * @param nfp The NFP to search - * @return true if the point was found - */ -bool in_nfp(const point_t& pt, const nfp_t& nfp) { - for (const auto& r : nfp) { - if (bg::touches(pt, r)) - return true; - } - - return false; -} - /** * @brief Indicating the result of %search_start_translation */ diff --git a/src/algo/select_next.hpp b/src/algo/select_next.hpp index 1cb29bc..095439f 100644 --- a/src/algo/select_next.hpp +++ b/src/algo/select_next.hpp @@ -7,9 +7,9 @@ namespace libnfporb { /** - * @brief Find the longest translation vector - * @param tvs The translation vectors - * @return The longest translation vector + * @brief Find the longest translation vector. + * @param tvs The translation vectors. + * @return The longest translation vector. */ TranslationVector find_longest(const std::vector& tvs) { coord_t len; @@ -28,27 +28,41 @@ TranslationVector find_longest(const std::vector& tvs) { } /** - * @brief Sort a std::vector of translation vectors by length - * @param tvs The std::vector to sort + * @brief Sort a std::vector of translation vectors by length. + * @param tvs The std::vector to sort. */ void sort_by_length(std::vector& tvs) { std::sort( tvs.begin( ), tvs.end( ), [ ]( const TranslationVector& lhs, const TranslationVector& rhs ) { coord_t llen = bg::length(segment_t { { 0, 0 }, lhs.vector_ }); coord_t rlen = bg::length(segment_t { { 0, 0 }, rhs.vector_ }); - return llen < rlen; + return llen < rlen; }); } /** - * @brief Select the next translation vector from all viable translations - * @param pA Polygon A - * @param rA The pertaining ring of polygon A - * @param rB Ring of B + * @brief Sort a std::vector of translation vectors by history count. + * @param history The history of used translation vectors. + * @param tvs The std::vector to sort. + */ +void sort_by_history_count(const History& history, std::vector& tvs) { + std::sort( tvs.begin( ), tvs.end( ), [&]( const TranslationVector& lhs, const TranslationVector& rhs ) { + size_t cl = count(history, lhs); + size_t cr = count(history, rhs); + return cl < cr; + }); +} + +/** + * @brief Select the next translation vector from all viable translations. + * @param nfp The NFP so far. + * @param pA Polygon A. + * @param rA The pertaining ring of polygon A. + * @param rB Ring of B. * @param feasibleVectors All viable translations (= all translations that lead to a valid slide, including already traversed ones) * @param history The history of all performed translations * @return The translation vector used for the next traversal step (slide) */ -TranslationVector select_next_translation_vector(const polygon_t& pA, const polygon_t::ring_type& rA, const polygon_t::ring_type& rB, std::vector feasibleVectors, const History& history) { +TranslationVector select_next_translation_vector(const nfp_t& nfp, const polygon_t& pA, const polygon_t::ring_type& rA, const polygon_t::ring_type& rB, std::vector feasibleVectors, const History& history) { if(feasibleVectors.size() == 1) { return feasibleVectors.front(); } @@ -68,10 +82,22 @@ TranslationVector select_next_translation_vector(const polygon_t& pA, const poly size_t minHistCnt = history.size() + 1; TranslationVector least_used; - sort_by_length(feasibleVectors); + sort_by_history_count(history, feasibleVectors); for(auto& candidate : feasibleVectors) { - if(count(history, candidate) == 0) { + point_t translated; + TranslationVector trimmed = trim_vector(rA, rB, candidate); + boost::geometry::transform(rB.front(), translated, trans::translate_transformer(trimmed.vector_.x_, trimmed.vector_.y_)); + if(!in_nfp(translated, nfp)) { + DEBUG_MSG("least unused, not in nfp", candidate); + return candidate; + } + } + + sort_by_length(feasibleVectors); + + for (auto& candidate : feasibleVectors) { + if (count(history, candidate) == 0) { DEBUG_MSG("longest unused", candidate); return candidate; } @@ -86,7 +112,7 @@ TranslationVector select_next_translation_vector(const polygon_t& pA, const poly } } - DEBUG_MSG("least used", least_used); + DEBUG_MSG("longest least used", least_used); return least_used; TranslationVector tv; diff --git a/src/algo/slide.hpp b/src/algo/slide.hpp index e2ae872..824a30b 100644 --- a/src/algo/slide.hpp +++ b/src/algo/slide.hpp @@ -75,7 +75,7 @@ SlideResult slide(polygon_t& pA, polygon_t::ring_type& rA, polygon_t::ring_type& return NO_LOOP; } - TranslationVector next = select_next_translation_vector(pA, rA, rB, feasibleVectors, history); + TranslationVector next = select_next_translation_vector(nfp, pA, rA, rB, feasibleVectors, history); if (equals(next.vector_, INVALID_POINT)) return NO_TRANSLATION; diff --git a/src/geometry.hpp b/src/geometry.hpp index 951f8ab..35cc696 100644 --- a/src/geometry.hpp +++ b/src/geometry.hpp @@ -522,6 +522,15 @@ point_t flip(const point_t& vec) { return flipped; } +bool is_parallel(const segment_t& s1, const segment_t& s2) { + coord_t dx1 = s1.first.x_ - s2.first.x_; + coord_t dy1 = s1.first.y_ - s2.first.y_; + coord_t dx2 = s1.second.x_ - s2.second.x_; + coord_t dy2 = s1.second.y_ - s2.second.y_; + + return dx1 == dx2 && dy2 == dy1; +} + enum Alignment { LEFT, RIGHT, @@ -625,6 +634,20 @@ psize_t find_point(const polygon_t::ring_type& ring, const point_t& pt) { return std::numeric_limits::max(); } +/** + * @brief Checks if a point exists in a NFP + * @param pt The point to look for + * @param nfp The NFP to search + * @return true if the point was found + */ +bool in_nfp(const point_t& pt, const nfp_t& nfp) { + for (const auto& r : nfp) { + if (bg::touches(pt, r)) + return true; + } + + return false; +} } #endif /* SRC_GEOMETRY_HPP_ */