diff --git a/cruft/util/region.hpp b/cruft/util/region.hpp index 9e6bb65d..8e2a227f 100644 --- a/cruft/util/region.hpp +++ b/cruft/util/region.hpp @@ -370,6 +370,26 @@ namespace cruft { rotate90 (cruft::region2 obj, int steps); + /////////////////////////////////////////////////////////////////////////// + /// Returns the vertices of the region (excluding last->first vertex) in + /// CCW winding. + /// + /// It assumes the base position is the min / extent is strictly positive. + template + std::array, 4> + path (cruft::region2 const &obj) + { + CHECK (all (obj.e > 0)); + + return { + obj.p, + obj.p + vector2 { 0, obj.e.h }, + obj.p + vector2 {obj.e.w, obj.e.h }, + obj.p + vector2 {obj.e.w, 0 }, + }; + } + + /////////////////////////////////////////////////////////////////////////// template std::ostream& operator<< (std::ostream&, const cruft::region&); diff --git a/test/region.cpp b/test/region.cpp index cdaa8730..90093f4f 100644 --- a/test/region.cpp +++ b/test/region.cpp @@ -286,5 +286,31 @@ main (int, char **) } } + // Test that 'path' returns expected values + { + // (-5, 3) (1, 3) + // + // + // (-5,-4)* (1,-4) + // + // Start at the bottom right corner. + + cruft::region2i const shape { + cruft::point2i { -5, -4, }, + cruft::point2i { 1, 3, }, + }; + + cruft::point2i const expected[] = { + cruft::point2i { -5, -4 }, + cruft::point2i { -5, 3 }, + cruft::point2i { 1, 3 }, + cruft::point2i { 1, -4 }, + }; + + auto const computed = path (shape); + + tap.expect (std::ranges::equal (computed, expected), "region2i path"); + } + return tap.status (); }