#pragma once #include #include #include #include #include #include #ifdef DEBUG #include #endif namespace mapbox { namespace geometry { namespace wagyu { template struct bound; template using bound_ptr = bound*; template struct edge { mapbox::geometry::point bot; mapbox::geometry::point top; double dx; edge(edge&& e) noexcept : bot(std::move(e.bot)), top(std::move(e.top)), dx(std::move(e.dx)) { } edge& operator=(edge&& e) noexcept { bot = std::move(e.bot); top = std::move(e.top); dx = std::move(e.dx); return *this; } edge(mapbox::geometry::point const& current, mapbox::geometry::point const& next_pt) noexcept : bot(current), top(current), dx(0.0) { if (current.y >= next_pt.y) { top = next_pt; } else { bot = next_pt; } double dy = static_cast(top.y - bot.y); if (value_is_zero(dy)) { dx = std::numeric_limits::infinity(); } else { dx = static_cast(top.x - bot.x) / dy; } } }; template using edge_ptr = edge*; template using edge_list = std::vector>; template using edge_list_itr = typename edge_list::iterator; template bool slopes_equal(edge const& e1, edge const& e2) { return (e1.top.y - e1.bot.y) * (e2.top.x - e2.bot.x) == (e1.top.x - e1.bot.x) * (e2.top.y - e2.bot.y); } template inline bool is_horizontal(edge const& e) { return std::isinf(e.dx); } template inline double get_current_x(edge const& edge, const T current_y) { if (current_y == edge.top.y) { return static_cast(edge.top.x); } else { return static_cast(edge.bot.x) + edge.dx * static_cast(current_y - edge.bot.y); } } #ifdef DEBUG template inline std::basic_ostream& operator<<(std::basic_ostream& out, const edge& e) { out << " Edge: " << std::endl; out << " bot x: " << e.bot.x << " y: " << e.bot.y << std::endl; out << " top x: " << e.top.x << " y: " << e.top.y << std::endl; return out; } template inline std::basic_ostream& operator<<(std::basic_ostream& out, edge_list const& edges) { out << "["; bool first = true; for (auto const& e : edges) { if (first) { first = false; } else { out << ","; } out << "[[" << e.bot.x << "," << e.bot.y << "],["; out << e.top.x << "," << e.top.y << "]]"; } out << "]"; return out; } #endif } } }