136 lines
3.6 KiB
C++
136 lines
3.6 KiB
C++
#pragma once
|
|
#include <algorithm>
|
|
#include <cstdint>
|
|
#include <iosfwd>
|
|
namespace renderive {
|
|
struct Point {
|
|
int x{};
|
|
int y{};
|
|
};
|
|
struct PointF {
|
|
double x{};
|
|
double y{};
|
|
};
|
|
struct Size {
|
|
int width{};
|
|
int height{};
|
|
[[nodiscard]] bool empty() const {
|
|
return width <= 0 || height <= 0;
|
|
}
|
|
bool operator==(const Size& other) const {
|
|
return width == other.width && height == other.height;
|
|
}
|
|
bool operator!=(const Size& other) const {
|
|
return !(*this == other);
|
|
}
|
|
};
|
|
struct Rect {
|
|
int x{};
|
|
int y{};
|
|
int width{};
|
|
int height{};
|
|
[[nodiscard]] bool empty() const {
|
|
return width <= 0 || height <= 0;
|
|
}
|
|
[[nodiscard]] int right() const {
|
|
return x + width;
|
|
}
|
|
[[nodiscard]] int bottom() const {
|
|
return y + height;
|
|
}
|
|
[[nodiscard]] Point top_left() const {
|
|
return {x, y};
|
|
}
|
|
[[nodiscard]] bool contains(Point point) const {
|
|
return point.x >= x && point.x <= right() && point.y >= y && point.y <= bottom();
|
|
}
|
|
[[nodiscard]] Rect intersected(const Rect& other) const {
|
|
int r = std::min(right(), other.right());
|
|
int b = std::min(bottom(), other.bottom());
|
|
int nx = std::max(x, other.x);
|
|
int ny = std::max(y, other.y);
|
|
int w = r - nx;
|
|
int h = b - ny;
|
|
if (w <= 0 || h <= 0)
|
|
return {};
|
|
return {nx, ny, w, h};
|
|
}
|
|
};
|
|
struct RectF {
|
|
double x{};
|
|
double y{};
|
|
double width{};
|
|
double height{};
|
|
[[nodiscard]] bool empty() const {
|
|
return width <= 0.0 || height <= 0.0;
|
|
}
|
|
[[nodiscard]] double right() const {
|
|
return x + width;
|
|
}
|
|
[[nodiscard]] double bottom() const {
|
|
return y + height;
|
|
}
|
|
[[nodiscard]] PointF top_left() const {
|
|
return {x, y};
|
|
}
|
|
[[nodiscard]] bool contains(PointF point) const {
|
|
return point.x >= x && point.x <= right() && point.y >= y && point.y <= bottom();
|
|
}
|
|
[[nodiscard]] RectF normalized() const {
|
|
double nx = x;
|
|
double ny = y;
|
|
double nw = width;
|
|
double nh = height;
|
|
if (nw < 0.0) {
|
|
nx += nw;
|
|
nw = -nw;
|
|
}
|
|
if (nh < 0.0) {
|
|
ny += nh;
|
|
nh = -nh;
|
|
}
|
|
return {nx, ny, nw, nh};
|
|
}
|
|
[[nodiscard]] RectF intersected(const RectF& other) const {
|
|
double r = std::min(right(), other.right());
|
|
double b = std::min(bottom(), other.bottom());
|
|
double nx = std::max(x, other.x);
|
|
double ny = std::max(y, other.y);
|
|
double w = r - nx;
|
|
double h = b - ny;
|
|
if (w <= 0.0 || h <= 0.0)
|
|
return {};
|
|
return {nx, ny, w, h};
|
|
}
|
|
};
|
|
enum class Orientation : std::uint8_t {
|
|
Horizontal,
|
|
Vertical
|
|
};
|
|
struct Range {
|
|
double origin;
|
|
double target;
|
|
[[nodiscard]] double size() const {
|
|
return target > origin ? target - origin : origin - target;
|
|
}
|
|
[[nodiscard]] double length() const {
|
|
return target - origin;
|
|
}
|
|
[[nodiscard]] double center() const {
|
|
return origin + (target - origin) / 2.0;
|
|
}
|
|
bool operator==(const Range& other) const {
|
|
return origin == other.origin && target == other.target;
|
|
}
|
|
bool operator!=(const Range& other) const {
|
|
return !(*this == other);
|
|
}
|
|
[[nodiscard]] bool contains(double value) const {
|
|
if (origin < target)
|
|
return value > origin - 0.0001 && value < target + 0.0001;
|
|
return value > target - 0.0001 && value < origin + 0.0001;
|
|
}
|
|
};
|
|
std::ostream& operator<<(std::ostream& stream, const Range& range);
|
|
} // namespace renderive
|