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