namespace vtr { /* * Point */ template Point::Point(T x_val, T y_val) : x_(x_val) , y_(y_val) { //pass } template Point::Point() { //pass } template T Point::x() const { return x_; } template T Point::y() const { return y_; } template bool operator==(Point lhs, Point rhs) { return lhs.x() == rhs.x() && lhs.y() == rhs.y(); } template bool operator!=(Point lhs, Point rhs) { return !(lhs == rhs); } template bool operator<(Point lhs, Point rhs) { return std::make_tuple(lhs.x(), lhs.y()) < std::make_tuple(rhs.x(), rhs.y()); } //Mutators template void Point::set(T x_val, T y_val) { x_ = x_val; y_ = y_val; } template void Point::set_x(T x_val) { x_ = x_val; } template void Point::set_y(T y_val) { y_ = y_val; } template void Point::swap() { std::swap(x_, y_); } /* * Rect */ template Rect::Rect(T left_val, T bottom_val, T right_val, T top_val) : Rect(Point(left_val, bottom_val), Point(right_val, top_val)) { //pass } template Rect::Rect(Point bottom_left_val, Point top_right_val) : bottom_left_(bottom_left_val) , top_right_(top_right_val) { //pass } template Rect::Rect() { //pass } template T Rect::xmin() const { return bottom_left_.x(); } template T Rect::xmax() const { return top_right_.x(); } template T Rect::ymin() const { return bottom_left_.y(); } template T Rect::ymax() const { return top_right_.y(); } template Point Rect::bottom_left() const { return bottom_left_; } template Point Rect::top_right() const { return top_right_; } template T Rect::width() const { return xmax() - xmin(); } template T Rect::height() const { return ymax() - ymin(); } template bool Rect::contains(Point point) const { //Up-to but not including right or top edges return point.x() >= xmin() && point.x() < xmax() && point.y() >= ymin() && point.y() < ymax(); } template bool Rect::strictly_contains(Point point) const { //Excluding edges return point.x() > xmin() && point.x() < xmax() && point.y() > ymin() && point.y() < ymax(); } template bool Rect::coincident(Point point) const { //Including right or top edges return point.x() >= xmin() && point.x() <= xmax() && point.y() >= ymin() && point.y() <= ymax(); } template bool operator==(const Rect& lhs, const Rect& rhs) { return lhs.bottom_left() == rhs.bottom_left() && lhs.top_right() == rhs.top_right(); } template bool operator!=(const Rect& lhs, const Rect& rhs) { return !(lhs == rhs); } template void Rect::set_xmin(T xmin_val) { bottom_left_.set_x(xmin_val); } template void Rect::set_ymin(T ymin_val) { bottom_left_.set_y(ymin_val); } template void Rect::set_xmax(T xmax_val) { top_right_.set_x(xmax_val); } template void Rect::set_ymax(T ymax_val) { top_right_.set_y(ymax_val); } /* * Line */ template Line::Line(std::vector> line_points) : points_(line_points) { //pass } template Rect Line::bounding_box() const { T xmin = std::numeric_limits::max(); T ymin = std::numeric_limits::max(); T xmax = std::numeric_limits::min(); T ymax = std::numeric_limits::min(); for (const auto& point : points()) { xmin = std::min(xmin, point.x()); ymin = std::min(ymin, point.y()); xmax = std::max(xmax, point.x()); ymax = std::max(ymax, point.y()); } return Rect(xmin, ymin, xmax, ymax); } template typename Line::point_range Line::points() const { return vtr::make_range(points_.begin(), points_.end()); } /* * RectUnion */ template RectUnion::RectUnion(std::vector> rectangles) : rects_(rectangles) { //pass } template Rect RectUnion::bounding_box() const { T xmin = std::numeric_limits::max(); T ymin = std::numeric_limits::max(); T xmax = std::numeric_limits::min(); T ymax = std::numeric_limits::min(); for (const auto& rect : rects_) { xmin = std::min(xmin, rect.xmin()); ymin = std::min(ymin, rect.ymin()); xmax = std::max(xmax, rect.xmax()); ymax = std::max(ymax, rect.ymax()); } return Rect(xmin, ymin, xmax, ymax); } template bool RectUnion::contains(Point point) const { for (const auto& rect : rects()) { if (rect.contains(point)) { return true; } } return false; } template bool RectUnion::strictly_contains(Point point) const { for (const auto& rect : rects()) { if (rect.strictly_contains(point)) { return true; } } return false; } template bool RectUnion::coincident(Point point) const { for (const auto& rect : rects()) { if (rect.coincident(point)) { return true; } } return false; } template typename RectUnion::rect_range RectUnion::rects() const { return vtr::make_range(rects_.begin(), rects_.end()); } template bool operator==(const RectUnion& lhs, const RectUnion& rhs) { //Currently checks for an identical *representation* (not whether the //representations are equivalent) if (lhs.rects_.size() != rhs.rects_.size()) { return false; } for (size_t i = 0; i < lhs.rects_.size(); ++i) { if (lhs.rects_[i] != rhs.rects_[i]) { return false; } } return true; } template bool operator!=(const RectUnion& lhs, const RectUnion& rhs) { return !(lhs == rhs); } } // namespace vtr