#ifndef TOONZ_PLUGIN_HELPER_UTILS_RECT_HPP__ #define TOONZ_PLUGIN_HELPER_UTILS_RECT_HPP__ #include #include #include class ToonzRect { public: double x0, y0; double x1, y1; ToonzRect() : x0(0), y0(0), x1(0), y1(0) {} ToonzRect(double x0, double y0, double x1, double y1) : x0(x0), y0(y0), x1(x1), y1(y1) {} ToonzRect(const ToonzRect &toonzRect) : x0(toonzRect.x0), y0(toonzRect.y0), x1(toonzRect.x1), y1(toonzRect.y1) {} bool equals(double a, double b, double err = DBL_EPSILON) const { return fabs(a - b) < err; } ToonzRect operator+(const ToonzRect &toonzRect) const; ToonzRect operator*(const ToonzRect &toonzRect) const; ToonzRect &operator+=(const ToonzRect &toonzRect); ToonzRect &operator*=(const ToonzRect &toonzRect); bool operator==(const ToonzRect &toonzRect) const; bool isEmpty() const; bool isContained(const ToonzRect &toonzRect) const; bool isOverlapped(const ToonzRect &toonzRect) const; ToonzRect enlarge(double x, double y) const; }; ToonzRect ToonzRect::operator+(const ToonzRect &toonzRect) const { if (isEmpty()) { return toonzRect; } else if (toonzRect.isEmpty()) { return *this; } return ToonzRect(std::min(x0, toonzRect.x0), std::min(y0, toonzRect.y0), std::max(x1, toonzRect.x1), std::max(y1, toonzRect.y1)); } ToonzRect ToonzRect::operator*(const ToonzRect &toonzRect) const { if (isEmpty() || toonzRect.isEmpty() || toonzRect.x1 < x0 || x1 < toonzRect.x0 || toonzRect.y1 < y0 || y1 < toonzRect.y0) { return ToonzRect(); } return ToonzRect(std::max(x0, toonzRect.x0), std::max(y0, toonzRect.y0), std::min(x1, toonzRect.x1), std::min(y1, toonzRect.y1)); } ToonzRect &ToonzRect::operator+=(const ToonzRect &toonzRect) { return *this = *this + toonzRect; } ToonzRect &ToonzRect::operator*=(const ToonzRect &toonzRect) { return *this = *this * toonzRect; } bool ToonzRect::operator==(const ToonzRect &toonzRect) const { return equals(x0, toonzRect.x0) && equals(y0, toonzRect.y0) && equals(x1, toonzRect.x1) && equals(y1, toonzRect.y1); } bool ToonzRect::isEmpty() const { if ((equals(x0, x1) && equals(y0, y1)) || x0 > x1 || y0 > y1) { return true; } return false; } bool ToonzRect::isContained(const ToonzRect &toonzRect) const { return toonzRect.x0 <= x0 && x1 <= toonzRect.x1 && toonzRect.y0 <= y0 && y1 <= toonzRect.y1; } bool ToonzRect::isOverlapped(const ToonzRect &toonzRect) const { return x0 <= toonzRect.x1 && x1 >= toonzRect.x0 && y0 <= toonzRect.y1 && y1 >= toonzRect.y0; } ToonzRect ToonzRect::enlarge(double x, double y) const { if (isEmpty()) { return *this; } return ToonzRect(x0 - x, y0 - y, x1 + x, y1 + y); } class ToonzPoint { public: double x, y; ToonzPoint() : x(0), y(0) {} ToonzPoint(double x, double y) : x(x), y(y) {} }; #endif