Files
Renderive/Core/base/Geometry.h
T
2026-08-02 12:15:48 +08:00

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