Skip to content

Commit

Permalink
Fixed winding order issues - now outputs properly counter-clockwise. c…
Browse files Browse the repository at this point in the history
…loses #51
  • Loading branch information
flippmoke committed Dec 7, 2016
1 parent d62519c commit 1176eac
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 19 deletions.
4 changes: 2 additions & 2 deletions include/mapbox/geometry/wagyu/build_result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ void push_ring_to_polygon(mapbox::geometry::polygon<T>& poly, ring_ptr<T>& r, bo
if (reverse_output) {
do {
lr.push_back({ ptIt->x, ptIt->y });
ptIt = ptIt->prev;
ptIt = ptIt->next;
} while (ptIt != firstPt);
} else {
do {
lr.push_back({ ptIt->x, ptIt->y });
ptIt = ptIt->next;
ptIt = ptIt->prev;
} while (ptIt != firstPt);
}
lr.push_back({ firstPt->x, firstPt->y }); // close the ring
Expand Down
15 changes: 15 additions & 0 deletions include/mapbox/geometry/wagyu/ring.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,21 @@ inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, t
return out;
}

template <class charT, class traits, typename T>
inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& out,
const std::deque<ring<T>>& rings) {
out << "START RING VECTOR" << std::endl;
for (auto& r : rings) {
if (!r.points) {
continue;
}
out << " ring: " << r.ring_index << std::endl;
out << r;
}
out << "END RING VECTOR" << std::endl;
return out;
}

template <class charT, class traits, typename T>
inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& out,
const hot_pixel_vector<T>& hp_vec) {
Expand Down
2 changes: 1 addition & 1 deletion include/mapbox/geometry/wagyu/vatti.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ bool execute_vatti(local_minimum_list<T>& minima_list,
clip_fill_type);

}
// std::clog << rings.all_rings << std::endl;
// std::clog << rings.rings << std::endl;
// std::clog << output_as_polygon(rings.all_rings[0]);
return true;
}
Expand Down
91 changes: 75 additions & 16 deletions tests/unit/vatti.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,65 @@
using namespace mapbox::geometry::wagyu;
using T = std::int64_t;

TEST_CASE("simple test for winding order - positive") {

// This ring is counter-clockwise
mapbox::geometry::linear_ring<std::int64_t> ring;
ring.push_back(mapbox::geometry::point<std::int64_t>(0, 0));
ring.push_back(mapbox::geometry::point<std::int64_t>(1, 0));
ring.push_back(mapbox::geometry::point<std::int64_t>(1, 1));
ring.push_back(mapbox::geometry::point<std::int64_t>(0, 1));
ring.push_back(mapbox::geometry::point<std::int64_t>(0, 0));

mapbox::geometry::wagyu::wagyu<std::int64_t> wagyu;
wagyu.add_ring(ring);

mapbox::geometry::multi_polygon<std::int64_t> solution;
wagyu.execute(mapbox::geometry::wagyu::clip_type_union, solution,
mapbox::geometry::wagyu::fill_type_positive,
mapbox::geometry::wagyu::fill_type_positive);

REQUIRE(solution.size() == 1);
// Check first polygon number of rings
REQUIRE(solution[0].size() == 1);

// Check Ring 1 is counter clockwise as well
REQUIRE(solution[0][0].size() == 5);
CHECK(solution[0][0][0].x == 1);
CHECK(solution[0][0][0].y == 0);

CHECK(solution[0][0][1].x == 1);
CHECK(solution[0][0][1].y == 1);

CHECK(solution[0][0][2].x == 0);
CHECK(solution[0][0][2].y == 1);

CHECK(solution[0][0][3].x == 0);
CHECK(solution[0][0][3].y == 0);

CHECK(solution[0][0][4].x == 1);
CHECK(solution[0][0][4].y == 0);
}

TEST_CASE("simple test for winding order - negative") {
mapbox::geometry::linear_ring<std::int64_t> ring;
ring.push_back(mapbox::geometry::point<std::int64_t>(0, 0));
ring.push_back(mapbox::geometry::point<std::int64_t>(1, 0));
ring.push_back(mapbox::geometry::point<std::int64_t>(1, 1));
ring.push_back(mapbox::geometry::point<std::int64_t>(0, 1));
ring.push_back(mapbox::geometry::point<std::int64_t>(0, 0));

mapbox::geometry::wagyu::wagyu<std::int64_t> wagyu;
wagyu.add_ring(ring);

mapbox::geometry::multi_polygon<std::int64_t> solution;
wagyu.execute(mapbox::geometry::wagyu::clip_type_union, solution,
mapbox::geometry::wagyu::fill_type_negative,
mapbox::geometry::wagyu::fill_type_negative);

REQUIRE(solution.size() == 0);
}

TEST_CASE("simple test of entire vatti") {

mapbox::geometry::wagyu::wagyu<T> clipper;
Expand Down Expand Up @@ -64,24 +123,24 @@ TEST_CASE("simple test of entire vatti") {
REQUIRE(solution[0][0].size() == 5);
CHECK(solution[0][0][0].x == -70312);
CHECK(solution[0][0][0].y == -55285);
CHECK(solution[0][0][1].x == -79102);
CHECK(solution[0][0][1].y == 0);
CHECK(solution[0][0][1].x == 85254);
CHECK(solution[0][0][1].y == -30747);
CHECK(solution[0][0][2].x == 58008);
CHECK(solution[0][0][2].y == 80592);
CHECK(solution[0][0][3].x == 85254);
CHECK(solution[0][0][3].y == -30747);
CHECK(solution[0][0][3].x == -79102);
CHECK(solution[0][0][3].y == 0);
CHECK(solution[0][0][4].x == -70312);
CHECK(solution[0][0][4].y == -55285);

REQUIRE(solution[0][1].size() == 5);
CHECK(solution[0][1][0].x == -65918);
CHECK(solution[0][1][0].y == -32502);
CHECK(solution[0][1][1].x == 51855);
CHECK(solution[0][1][1].y == -21089);
CHECK(solution[0][1][1].x == -50098);
CHECK(solution[0][1][1].y == 4394);
CHECK(solution[0][1][2].x == 44824);
CHECK(solution[0][1][2].y == 42149);
CHECK(solution[0][1][3].x == -50098);
CHECK(solution[0][1][3].y == 4394);
CHECK(solution[0][1][3].x == 51855);
CHECK(solution[0][1][3].y == -21089);
CHECK(solution[0][1][4].x == -65918);
CHECK(solution[0][1][4].y == -32502);

Expand Down Expand Up @@ -146,24 +205,24 @@ TEST_CASE("simple test of entire vatti - reverse output") {
REQUIRE(solution[0][0].size() == 5);
CHECK(solution[0][0][0].x == -70312);
CHECK(solution[0][0][0].y == -55285);
CHECK(solution[0][0][1].x == 85254);
CHECK(solution[0][0][1].y == -30747);
CHECK(solution[0][0][1].x == -79102);
CHECK(solution[0][0][1].y == 0);
CHECK(solution[0][0][2].x == 58008);
CHECK(solution[0][0][2].y == 80592);
CHECK(solution[0][0][3].x == -79102);
CHECK(solution[0][0][3].y == 0);
CHECK(solution[0][0][3].x == 85254);
CHECK(solution[0][0][3].y == -30747);
CHECK(solution[0][0][4].x == -70312);
CHECK(solution[0][0][4].y == -55285);

REQUIRE(solution[0][1].size() == 5);
CHECK(solution[0][1][0].x == -65918);
CHECK(solution[0][1][0].y == -32502);
CHECK(solution[0][1][1].x == -50098);
CHECK(solution[0][1][1].y == 4394);
CHECK(solution[0][1][1].x == 51855);
CHECK(solution[0][1][1].y == -21089);
CHECK(solution[0][1][2].x == 44824);
CHECK(solution[0][1][2].y == 42149);
CHECK(solution[0][1][3].x == 51855);
CHECK(solution[0][1][3].y == -21089);
CHECK(solution[0][1][3].x == -50098);
CHECK(solution[0][1][3].y == 4394);
CHECK(solution[0][1][4].x == -65918);
CHECK(solution[0][1][4].y == -32502);

Expand Down
6 changes: 6 additions & 0 deletions tests/util/boost_geometry_adapters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ struct tag<mapbox::geometry::linear_ring<CoordinateType>> {
using type = ring_tag;
};

template <typename CoordinateType>
struct point_order<mapbox::geometry::linear_ring<CoordinateType> >
{
static const order_selector value = counterclockwise;
};

template <typename CoordinateType>
struct tag<mapbox::geometry::polygon<CoordinateType>> {
using type = polygon_tag;
Expand Down

0 comments on commit 1176eac

Please sign in to comment.