Files
esengine/packages/engine/src/math/rect.rs

149 lines
4.0 KiB
Rust
Raw Normal View History

//! Rectangle implementation.
//! 矩形实现。
use super::Vec2;
/// Axis-aligned rectangle.
/// 轴对齐矩形。
///
/// # Examples | 示例
/// ```rust
/// let rect = Rect::new(10.0, 20.0, 100.0, 50.0);
/// let point = Vec2::new(50.0, 40.0);
/// assert!(rect.contains_point(point));
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct Rect {
/// X position (left edge).
/// X位置左边缘
pub x: f32,
/// Y position (top edge).
/// Y位置上边缘
pub y: f32,
/// Width.
/// 宽度。
pub width: f32,
/// Height.
/// 高度。
pub height: f32,
}
impl Rect {
/// Create a new rectangle.
/// 创建新矩形。
#[inline]
pub const fn new(x: f32, y: f32, width: f32, height: f32) -> Self {
Self { x, y, width, height }
}
/// Create a rectangle from two corner points.
/// 从两个角点创建矩形。
#[inline]
pub fn from_corners(min: Vec2, max: Vec2) -> Self {
Self {
x: min.x,
y: min.y,
width: max.x - min.x,
height: max.y - min.y,
}
}
/// Create a rectangle centered at a point.
/// 创建以某点为中心的矩形。
#[inline]
pub fn from_center(center: Vec2, width: f32, height: f32) -> Self {
Self {
x: center.x - width * 0.5,
y: center.y - height * 0.5,
width,
height,
}
}
/// Get the minimum (top-left) corner.
/// 获取最小(左上)角点。
#[inline]
pub fn min(&self) -> Vec2 {
Vec2::new(self.x, self.y)
}
/// Get the maximum (bottom-right) corner.
/// 获取最大(右下)角点。
#[inline]
pub fn max(&self) -> Vec2 {
Vec2::new(self.x + self.width, self.y + self.height)
}
/// Get the center point.
/// 获取中心点。
#[inline]
pub fn center(&self) -> Vec2 {
Vec2::new(self.x + self.width * 0.5, self.y + self.height * 0.5)
}
/// Get the size as a vector.
/// 获取尺寸向量。
#[inline]
pub fn size(&self) -> Vec2 {
Vec2::new(self.width, self.height)
}
/// Check if the rectangle contains a point.
/// 检查矩形是否包含某点。
#[inline]
pub fn contains_point(&self, point: Vec2) -> bool {
point.x >= self.x
&& point.x <= self.x + self.width
&& point.y >= self.y
&& point.y <= self.y + self.height
}
/// Check if this rectangle intersects with another.
/// 检查此矩形是否与另一个相交。
#[inline]
pub fn intersects(&self, other: &Rect) -> bool {
self.x < other.x + other.width
&& self.x + self.width > other.x
&& self.y < other.y + other.height
&& self.y + self.height > other.y
}
/// Get the intersection of two rectangles.
/// 获取两个矩形的交集。
pub fn intersection(&self, other: &Rect) -> Option<Rect> {
let x = self.x.max(other.x);
let y = self.y.max(other.y);
let right = (self.x + self.width).min(other.x + other.width);
let bottom = (self.y + self.height).min(other.y + other.height);
if right > x && bottom > y {
Some(Rect::new(x, y, right - x, bottom - y))
} else {
None
}
}
/// Get the union of two rectangles (bounding box).
/// 获取两个矩形的并集(包围盒)。
pub fn union(&self, other: &Rect) -> Rect {
let x = self.x.min(other.x);
let y = self.y.min(other.y);
let right = (self.x + self.width).max(other.x + other.width);
let bottom = (self.y + self.height).max(other.y + other.height);
Rect::new(x, y, right - x, bottom - y)
}
/// Expand the rectangle by a margin.
/// 按边距扩展矩形。
#[inline]
pub fn expand(&self, margin: f32) -> Rect {
Rect::new(
self.x - margin,
self.y - margin,
self.width + margin * 2.0,
self.height + margin * 2.0,
)
}
}