diff --git a/src/domain/board.cpp b/src/domain/board.cpp index 7074fa7..a53f2db 100644 --- a/src/domain/board.cpp +++ b/src/domain/board.cpp @@ -12,6 +12,7 @@ #include #include "utils/signum.hpp" +#include "utils/vector_utils.hpp" #include "conflicts/conflict_edge_in_polygon.hpp" #include "board.hpp" @@ -66,7 +67,33 @@ void sort_points_by_vector_orientation(vector& points, Point const& vecto } //****************************************************************************** -Board::Board(vector>& polygons) +unique_ptr Board::Builder::build() { + return make_unique(move(polygons)); +} + +//****************************************************************************** +void Board::Builder::add_polygon(string const& name, initializer_list points) { + polygons.push_back(make_unique(name, from_init_list(points))); +} + +//****************************************************************************** +void Board::Builder::add_polygon(string const& name, vector>&& points) { + polygons.push_back(make_unique(name, move(points))); +} + +//****************************************************************************** +void Board::Builder::add_polygon_from_box(string const& name, Point const p1, Point const p3) { + vector> points(4); + points[0] = make_unique(p1.x, p1.y); + points[1] = make_unique(p1.x, p3.y); + points[2] = make_unique(p3.x, p3.y); + points[3] = make_unique(p3.x, p1.y); + + polygons.push_back(make_unique(name, move(points))); +} + +//****************************************************************************** +Board::Board(vector>&& polygons) : conflict_manager(&line_policy_manager) , line_policy_manager(params, &conflict_manager) , polygons(move(polygons)) { diff --git a/src/domain/board.hpp b/src/domain/board.hpp index fd2936b..baae404 100644 --- a/src/domain/board.hpp +++ b/src/domain/board.hpp @@ -35,13 +35,23 @@ class Board : public Entity, public Visitable { std::vector edges; public: - Params params; + //************************************************************************** + class Builder { + public: + + void add_polygon(std::string const& name, std::initializer_list points); + void add_polygon(std::string const& name, std::vector>&& points); + void add_polygon_from_box(std::string const& name, Point const p1, Point const p3); + + [[nodiscard]] std::unique_ptr build(); -// Board(std::initializer_list _polygons); - explicit Board(std::vector>& polygons); - Board(); // TODO + private: + std::vector> polygons; + }; + + Params params; - void add_polygon(Polygon const polygon); // TODO + explicit Board(std::vector>&& polygons); /// Mesh resolution independant detection tasks ///************************************************************************* diff --git a/src/domain/geometrics/polygon.cpp b/src/domain/geometrics/polygon.cpp index 53eaad0..fa32a98 100644 --- a/src/domain/geometrics/polygon.cpp +++ b/src/domain/geometrics/polygon.cpp @@ -16,70 +16,29 @@ using namespace std; //****************************************************************************** -Polygon::Polygon(initializer_list points) -: bounding({ begin(points)->x, begin(points)->x, begin(points)->y, begin(points)->y }) { - for(auto const& point : points) - this->points.push_back(make_unique(point)); // TODO do not use initializer_list because of copies - this->points.shrink_to_fit(); - - rotation = detect_rotation(this->points); - - Point const* prev = this->points.back().get(); - for(auto const& point : this->points) { - edges.push_back(make_unique(prev, point.get())); - prev = point.get(); - } - edges.shrink_to_fit(); - - detect_bounding(); +Polygon::Polygon(string const& name, vector>&& points) +: rotation(detect_rotation(points)) +, bounding(detect_bounding(points)) +, name(name) +, points(move(points)) +, edges(detect_edges(this->points)) +{ detect_edge_normal(); } //****************************************************************************** -Polygon::Polygon(string name, initializer_list points) -: bounding({ begin(points)->x, begin(points)->x, begin(points)->y, begin(points)->y }) -, name(move(name)) { - for(auto const& point : points) - this->points.push_back(make_unique(point)); // TODO do not use initializer_list because of copies - this->points.shrink_to_fit(); - - rotation = detect_rotation(this->points); - - Point const* prev = this->points.back().get(); - for(auto const& point : this->points) { - edges.push_back(make_unique(prev, point.get())); - prev = point.get(); - } - edges.shrink_to_fit(); - - detect_bounding(); - detect_edge_normal(); -} - -//****************************************************************************** -/* -Polygon::Polygon(vector> _points) -: points(_points) { - for(unique_ptr& point : points) { - if(point->x < bounding[XMIN]) bounding[XMIN] = point->x; - if(point->x > bounding[XMAX]) bounding[XMAX] = point->x; - if(point->y < bounding[YMIN]) bounding[YMIN] = point->y; - if(point->y > bounding[YMAX]) bounding[YMAX] = point->y; - } - points.shrink_to_fit(); - - rotation = detect_rotation(points); +vector> detect_edges(vector> const& points) { + vector> edges; Point const* prev = points.back().get(); - for(unique_ptr& point : points) { + for(auto const & point : points) { edges.push_back(make_unique(prev, point.get())); prev = point.get(); } edges.shrink_to_fit(); - detect_edge_normal(); + return edges; } -*/ /// Cf. https://rosettacode.org/wiki/Shoelace_formula_for_polygonal_area#C.2B.2B /// Cf. https://www.baeldung.com/cs/list-polygon-points-clockwise @@ -89,7 +48,7 @@ Polygon::Polygon(vector> _points) /// FDTD mesh is orthogonal. ///***************************************************************************** template -Polygon::Rotation detect_rotation(T const& points) { +Polygon::Rotation detect_rotation(T const& points) noexcept { double left_sum = 0.0; double right_sum = 0.0; @@ -112,17 +71,25 @@ Polygon::Rotation detect_rotation(T const& points) { } //****************************************************************************** -template Polygon::Rotation detect_rotation(std::vector> const&); -template Polygon::Rotation detect_rotation(std::vector const&); +template Polygon::Rotation detect_rotation(std::vector> const&) noexcept; +template Polygon::Rotation detect_rotation(std::vector const&) noexcept; //****************************************************************************** -void Polygon::detect_bounding() { +Bounding2D detect_bounding(vector> const& points) noexcept { + Bounding2D bounding({ + (*begin(points))->x, + (*begin(points))->x, + (*begin(points))->y, + (*begin(points))->y }); + for(auto const& point : points) { if(point->x < bounding[XMIN]) bounding[XMIN] = point->x; if(point->x > bounding[XMAX]) bounding[XMAX] = point->x; if(point->y < bounding[YMIN]) bounding[YMIN] = point->y; if(point->y > bounding[YMAX]) bounding[YMAX] = point->y; } + + return bounding; } /// YMAX | YMAX @@ -137,7 +104,7 @@ void Polygon::detect_bounding() { /// YMIN | YMIN /// CW | CCW ///***************************************************************************** -void Polygon::detect_edge_normal() { +void Polygon::detect_edge_normal() noexcept { switch(rotation) { case Rotation::CW: for(auto const& edge : edges) { diff --git a/src/domain/geometrics/polygon.hpp b/src/domain/geometrics/polygon.hpp index f25fea9..9da8ecb 100644 --- a/src/domain/geometrics/polygon.hpp +++ b/src/domain/geometrics/polygon.hpp @@ -32,8 +32,7 @@ class Polygon , public IConflictOrigin /*, public IMeshLineOrigin*/ { private: - void detect_bounding(); // TODO - void detect_edge_normal(); + void detect_edge_normal() noexcept; public: enum class Rotation { @@ -41,26 +40,24 @@ class Polygon CW, CCW, COLINEAR - } rotation; + } const rotation; enum class Type { SHAPE, PORT } type; // TODO usefull? - Bounding2D bounding; - std::string name; // TODO + Bounding2D const bounding; + std::string const name; - // TODO rm unique_ptr ? - std::vector> points; + std::vector> const points; /// edge[0] is between points[n] & points[0] /// edge[x] is between points[x-1] & points[x] ///************************************************************************* - std::vector> edges; + std::vector> const edges; - explicit Polygon(std::initializer_list points); - Polygon(std::string name, std::initializer_list points); + Polygon(std::string const& name, std::vector>&& points); // relation::PolygonEdge relation_to(Edge const* edge); relation::PolygonPoint relation_to(Point const& point) const; @@ -72,6 +69,12 @@ class Polygon /// These are the two declaration authorized. ///***************************************************************************** -template Polygon::Rotation detect_rotation(T const& points); -extern template Polygon::Rotation detect_rotation(std::vector> const&); -extern template Polygon::Rotation detect_rotation(std::vector const&); +template Polygon::Rotation detect_rotation(T const& points) noexcept; +extern template Polygon::Rotation detect_rotation(std::vector> const&) noexcept; +extern template Polygon::Rotation detect_rotation(std::vector const&) noexcept; + +//****************************************************************************** +Bounding2D detect_bounding(std::vector> const& points) noexcept; + +//****************************************************************************** +std::vector> detect_edges(std::vector> const& points); diff --git a/src/domain/meshline_policy_manager.cpp b/src/domain/meshline_policy_manager.cpp index a6ea044..2146707 100644 --- a/src/domain/meshline_policy_manager.cpp +++ b/src/domain/meshline_policy_manager.cpp @@ -7,7 +7,7 @@ #include #include -#include "utils/vector_view.hpp" +#include "utils/vector_utils.hpp" #include "conflict_manager.hpp" #include "meshline_policy_manager.hpp" diff --git a/src/infra/serializers/serializer_to_plantuml.cpp b/src/infra/serializers/serializer_to_plantuml.cpp index 820b2d5..d4b0c9b 100644 --- a/src/infra/serializers/serializer_to_plantuml.cpp +++ b/src/infra/serializers/serializer_to_plantuml.cpp @@ -13,7 +13,7 @@ #include "domain/mesh/interval.hpp" #include "domain/board.hpp" #include "infra/utils/to_string.hpp" -#include "utils/vector_view.hpp" +#include "utils/vector_utils.hpp" #include "serializer_to_plantuml.hpp" diff --git a/src/infra/serializers/serializer_to_prettyprint.cpp b/src/infra/serializers/serializer_to_prettyprint.cpp index cab6813..2823df6 100644 --- a/src/infra/serializers/serializer_to_prettyprint.cpp +++ b/src/infra/serializers/serializer_to_prettyprint.cpp @@ -15,7 +15,7 @@ #include "domain/mesh/interval.hpp" #include "domain/board.hpp" #include "infra/utils/to_string.hpp" -#include "utils/vector_view.hpp" +#include "utils/vector_utils.hpp" #include "utils/color.hpp" #include "serializer_to_prettyprint.hpp" diff --git a/src/main.cpp b/src/main.cpp index c4e6576..cd7eb7c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,26 +15,6 @@ using namespace std; -//****************************************************************************** -Polygon from_box(string name, Point p1, Point p3) { - return Polygon(name, { - { p1.x, p1.y }, - { p1.x, p3.y }, - { p3.x, p3.y }, - { p3.x, p1.y } - }); -} -/* -initializer_list const& from_box(Point p1, Point p3) { - return { - { p1.x, p1.y }, - { p1.x, p3.y }, - { p3.x, p3.y }, - { p3.x, p1.y } - }; -} -*/ - //****************************************************************************** void print(vector> const& mesh_h, vector> const& mesh_v) { cout << "\nH :" << endl; @@ -62,16 +42,16 @@ int main(int argc, char* argv[]) { if(string(argv[1]) == "lpf") { unique_ptr lpf = [] { - vector> tmp; - tmp.push_back(make_unique(from_box("MS1", { 16.1, -26.5 }, { 20.6, -26 }))); - tmp.push_back(make_unique(from_box("MS2", { 20.6, -36.5 }, { 22.1, -16 }))); - tmp.push_back(make_unique(from_box("MS3", { 22.1, -26.5 }, { 40.1, -26 }))); - tmp.push_back(make_unique(from_box("MS4", { 40.1, -36.5 }, { 42.6, -16 }))); - tmp.push_back(make_unique(from_box("MS5", { 42.6, -26.5 }, { 60.6, -26 }))); - tmp.push_back(make_unique(from_box("MS6", { 60.6, -36.5 }, { 62.1, -16 }))); - tmp.push_back(make_unique(from_box("MS7", { 62.1, -26.5 }, { 66.6, -26 }))); - - return make_unique(tmp); + Board::Builder builder; + builder.add_polygon_from_box("MS1", { 16.1, -26.5 }, { 20.6, -26 }); + builder.add_polygon_from_box("MS2", { 20.6, -36.5 }, { 22.1, -16 }); + builder.add_polygon_from_box("MS3", { 22.1, -26.5 }, { 40.1, -26 }); + builder.add_polygon_from_box("MS4", { 40.1, -36.5 }, { 42.6, -16 }); + builder.add_polygon_from_box("MS5", { 42.6, -26.5 }, { 60.6, -26 }); + builder.add_polygon_from_box("MS6", { 60.6, -36.5 }, { 62.1, -16 }); + builder.add_polygon_from_box("MS7", { 62.1, -26.5 }, { 66.6, -26 }); + + return builder.build(); } (); lpf->params.lmin = 1; @@ -98,55 +78,55 @@ int main(int argc, char* argv[]) { } else if(string(argv[1]) == "stub") { unique_ptr stub = [] { - vector> tmp; - tmp.push_back(make_unique(from_box("MS1", { 31.1, -44.8024 }, { 51.3539, -42.0164 }))); - tmp.push_back(make_unique(from_box("MS2", { 120.029, -44.8024 }, { 140.283, -42.0164 }))); - tmp.push_back(make_unique(from_box("MS3", { 51.6077, -42.0164 }, { 51.3539, -31 }))); - tmp.push_back(make_unique(from_box("MS4", { 120.024, -42.0164 }, { 119.78, -31 }))); - tmp.push_back(make_unique(from_box("MS5", { 109.208, -43.9276 }, { 119.775, -42.8913 }))); - tmp.push_back(make_unique(from_box("MS6", { 51.6077, -43.9276 }, { 62.1753, -42.8913 }))); - tmp.push_back(make_unique(from_box("MS7", { 70.3673, -42.8674 }, { 62.1753, -33.2952 }))); - tmp.push_back(make_unique(from_box("MS8", { 109.208, -42.8674 }, { 101.016, -33.2952 }))); - tmp.push_back(make_unique(from_box("MS9", { 90.96, -42.8674 }, { 80.4229, -33.1334 }))); - tmp.push_back(make_unique(from_box("MS10", { 70.3673, -43.9514 }, { 80.4229, -42.8674 }))); - tmp.push_back(make_unique(from_box("MS11", { 90.96, -43.9514 }, { 101.016, -42.8674 }))); - tmp.push_back(make_unique(Polygon("MS12", { + Board::Builder builder; + builder.add_polygon_from_box("MS1", { 31.1, -44.8024 }, { 51.3539, -42.0164 }); + builder.add_polygon_from_box("MS2", { 120.029, -44.8024 }, { 140.283, -42.0164 }); + builder.add_polygon_from_box("MS3", { 51.6077, -42.0164 }, { 51.3539, -31 }); + builder.add_polygon_from_box("MS4", { 120.024, -42.0164 }, { 119.78, -31 }); + builder.add_polygon_from_box("MS5", { 109.208, -43.9276 }, { 119.775, -42.8913 }); + builder.add_polygon_from_box("MS6", { 51.6077, -43.9276 }, { 62.1753, -42.8913 }); + builder.add_polygon_from_box("MS7", { 70.3673, -42.8674 }, { 62.1753, -33.2952 }); + builder.add_polygon_from_box("MS8", { 109.208, -42.8674 }, { 101.016, -33.2952 }); + builder.add_polygon_from_box("MS9", { 90.96, -42.8674 }, { 80.4229, -33.1334 }); + builder.add_polygon_from_box("MS10", { 70.3673, -43.9514 }, { 80.4229, -42.8674 }); + builder.add_polygon_from_box("MS11", { 90.96, -43.9514 }, { 101.016, -42.8674 }); + builder.add_polygon("MS12", { { 51.6077, -42.0164 }, { 51.3539, -42.0164 }, { 51.3539, -44.8024 }, { 51.4808, -44.8024 }, { 51.4808, -43.9276 }, - { 51.6077, -43.9276 }}))); - tmp.push_back(make_unique(Polygon("MS13", { + { 51.6077, -43.9276 }}); + builder.add_polygon("MS13", { { 70.3673, -42.8674 }, { 62.1753, -42.8674 }, { 62.1753, -43.9276 }, { 66.2713, -43.9276 }, { 66.2713, -43.9514 }, - { 70.3673, -43.9514 }}))); - tmp.push_back(make_unique(Polygon("MS14", { + { 70.3673, -43.9514 }}); + builder.add_polygon("MS14", { { 90.96, -42.8674 }, { 80.4229, -42.8674 }, { 80.4229, -43.9514 }, { 85.6915, -43.9514 }, { 85.6915, -43.9514 }, - { 90.96, -43.9514 }}))); - tmp.push_back(make_unique(Polygon("MS15", { + { 90.96, -43.9514 }}); + builder.add_polygon("MS15", { { 109.208, -42.8674 }, { 101.016, -42.8674 }, { 101.016, -43.9514 }, { 105.112, -43.9514 }, { 105.112, -43.9276 }, - { 109.208, -43.9276 }}))); - tmp.push_back(make_unique(Polygon("MS16", { + { 109.208, -43.9276 }}); + builder.add_polygon("MS16", { { 120.029, -42.0164 }, { 119.775, -42.0164 }, { 119.775, -43.9276 }, { 119.902, -43.9276 }, { 119.902, -44.8024 }, - { 120.029, -44.8024 }}))); + { 120.029, -44.8024 }}); - return make_unique(tmp); + return builder.build(); } (); stub->params.lmin = 0; diff --git a/src/utils/vector_view.hpp b/src/utils/vector_utils.hpp similarity index 62% rename from src/utils/vector_view.hpp rename to src/utils/vector_utils.hpp index 49bbeea..342fac1 100644 --- a/src/utils/vector_view.hpp +++ b/src/utils/vector_utils.hpp @@ -6,6 +6,7 @@ #pragma once +#include #include #include @@ -20,3 +21,15 @@ std::vector create_view(std::vector> const& original) noe return view; } + +//****************************************************************************** +template +std::vector> from_init_list(std::initializer_list const& original) noexcept { + std::vector> out; + + for(auto const& it : original) + out.push_back(std::make_unique(it)); + + out.shrink_to_fit(); + return out; +} diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 3a594c2..f96004c 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -24,7 +24,7 @@ if( Catch2_FOUND ) "${CMAKE_CURRENT_SOURCE_DIR}/domain/test_board.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/infra/utils/test_to_string.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/utils/test_signum.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/utils/test_vector_view.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/utils/test_vector_utils.cpp" ) target_compile_definitions( openemsh_unittest diff --git a/test/unit/utils/test_vector_view.cpp b/test/unit/utils/test_vector_utils.cpp similarity index 61% rename from test/unit/utils/test_vector_view.cpp rename to test/unit/utils/test_vector_utils.cpp index 0f157be..ece5a71 100644 --- a/test/unit/utils/test_vector_view.cpp +++ b/test/unit/utils/test_vector_utils.cpp @@ -7,17 +7,20 @@ #include #include +#include -#include "utils/vector_view.hpp" +#include "utils/vector_utils.hpp" /// @test template std::vector create_view( /// std::vector> const& original) +/// @test template std::vector> from_init_list( +/// std::initializer_list const& original) ///***************************************************************************** //****************************************************************************** SCENARIO("template std::vector create_view( \ std::vector> \ -const& original)", "[utils][vector_view]") { +const& original)", "[utils][vector_utils]") { GIVEN("A vector of unique_ptr to string with members") { std::vector> a; a.emplace_back(std::make_unique("aa")); @@ -43,3 +46,25 @@ const& original)", "[utils][vector_view]") { } } } + +//****************************************************************************** +SCENARIO("template std::vector> from_init_list( \ +std::initializer_list const& original)", "[vector_utils]") { + GIVEN("An initializer list of strings") { + std::initializer_list a({ + std::string("aa"), + std::string("b"), + std::string("333"), + std::string("dd") }); + + THEN("Should return an equivalent vector of unique_ptr to const strings") { + std::vector> b = from_init_list(a); + REQUIRE(b.size() == a.size()); + for(auto it = std::make_pair(begin(a), begin(b)) + ; it.first != end(a) + ; ++it.first, ++it.second) { + REQUIRE(*(it.second->get()) == *it.first); + } + } + } +}