78 lines
2.2 KiB
C
78 lines
2.2 KiB
C
|
|
#pragma once
|
||
|
|
|
||
|
|
#include <algorithm>
|
||
|
|
#include <core/vec2.h>
|
||
|
|
#include <core/size.h>
|
||
|
|
|
||
|
|
namespace extra2d {
|
||
|
|
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
// 2D 矩形
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
struct Rect {
|
||
|
|
Point origin;
|
||
|
|
Size size;
|
||
|
|
|
||
|
|
constexpr Rect() = default;
|
||
|
|
constexpr Rect(float x, float y, float w, float h)
|
||
|
|
: origin(x, y), size(w, h) {}
|
||
|
|
constexpr Rect(const Point &o, const Size &s) : origin(o), size(s) {}
|
||
|
|
|
||
|
|
float left() const { return origin.x; }
|
||
|
|
float top() const { return origin.y; }
|
||
|
|
float right() const { return origin.x + size.width; }
|
||
|
|
float bottom() const { return origin.y + size.height; }
|
||
|
|
float width() const { return size.width; }
|
||
|
|
float height() const { return size.height; }
|
||
|
|
Point center() const {
|
||
|
|
return {origin.x + size.width * 0.5f, origin.y + size.height * 0.5f};
|
||
|
|
}
|
||
|
|
|
||
|
|
bool empty() const { return size.empty(); }
|
||
|
|
|
||
|
|
bool containsPoint(const Point &p) const {
|
||
|
|
return p.x >= left() && p.x <= right() && p.y >= top() && p.y <= bottom();
|
||
|
|
}
|
||
|
|
|
||
|
|
bool contains(const Rect &r) const {
|
||
|
|
return r.left() >= left() && r.right() <= right() && r.top() >= top() &&
|
||
|
|
r.bottom() <= bottom();
|
||
|
|
}
|
||
|
|
|
||
|
|
bool intersects(const Rect &r) const {
|
||
|
|
return !(left() > r.right() || right() < r.left() || top() > r.bottom() ||
|
||
|
|
bottom() < r.top());
|
||
|
|
}
|
||
|
|
|
||
|
|
Rect intersection(const Rect &r) const {
|
||
|
|
float l = std::max(left(), r.left());
|
||
|
|
float t = std::max(top(), r.top());
|
||
|
|
float ri = std::min(right(), r.right());
|
||
|
|
float b = std::min(bottom(), r.bottom());
|
||
|
|
if (l < ri && t < b)
|
||
|
|
return {l, t, ri - l, b - t};
|
||
|
|
return {};
|
||
|
|
}
|
||
|
|
|
||
|
|
Rect unionWith(const Rect &r) const {
|
||
|
|
if (empty())
|
||
|
|
return r;
|
||
|
|
if (r.empty())
|
||
|
|
return *this;
|
||
|
|
float l = std::min(left(), r.left());
|
||
|
|
float t = std::min(top(), r.top());
|
||
|
|
float ri = std::max(right(), r.right());
|
||
|
|
float b = std::max(bottom(), r.bottom());
|
||
|
|
return {l, t, ri - l, b - t};
|
||
|
|
}
|
||
|
|
|
||
|
|
bool operator==(const Rect &r) const {
|
||
|
|
return origin == r.origin && size == r.size;
|
||
|
|
}
|
||
|
|
bool operator!=(const Rect &r) const { return !(*this == r); }
|
||
|
|
|
||
|
|
static constexpr Rect Zero() { return {0, 0, 0, 0}; }
|
||
|
|
};
|
||
|
|
|
||
|
|
} // namespace extra2d
|