2016-03-26 00:24:04 +13:00
|
|
|
#ifndef TOONZ_PLUGIN_HELPER_UTILS_RECT_HPP__
|
|
|
|
#define TOONZ_PLUGIN_HELPER_UTILS_RECT_HPP__
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cmath>
|
|
|
|
#include <cfloat>
|
|
|
|
|
|
|
|
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
|