use crate::{iline, ILine};
use bevy_math::{ivec2, uvec2, vec2, IRect, IVec2, Rect, URect, UVec2, Vec2};
#[inline]
#[must_use]
pub fn distance_squared_to_upoint(a: UVec2, b: UVec2) -> f32 {
a.as_vec2().distance_squared(b.as_vec2())
}
#[inline]
#[must_use]
pub fn distance_to_upoint(a: UVec2, b: UVec2) -> f32 {
distance_squared_to_upoint(a, b).sqrt()
}
#[inline]
#[must_use]
pub fn distance_squared_to_line(p: Vec2, line: &[Vec2; 2]) -> f32 {
let v = line[0];
let w = line[1];
if v == w {
return p.distance_squared(v);
}
let l2 = v.distance_squared(w);
let t = ((p - v).dot(w - v) / l2).clamp(0., 1.);
let projection = v + t * (w - v);
p.distance_squared(projection)
}
#[inline]
#[must_use]
pub fn distance_to_line(p: Vec2, line: &[Vec2; 2]) -> f32 {
distance_squared_to_line(p, line).sqrt()
}
#[inline]
#[must_use]
pub fn rect_points(rect: &Rect) -> [Vec2; 4] {
[
rect.min,
rect.min + vec2(rect.width(), 0.),
rect.max,
rect.min + vec2(0., rect.height()),
]
}
#[inline]
#[must_use]
pub fn irect_points(rect: &IRect) -> [IVec2; 4] {
[
rect.min,
rect.min + ivec2(rect.width(), 0),
rect.max,
rect.min + ivec2(0, rect.height()),
]
}
#[inline]
#[must_use]
pub fn urect_points(rect: &URect) -> [UVec2; 4] {
[
rect.min,
rect.min + uvec2(rect.width(), 0),
rect.max,
rect.min + uvec2(0, rect.height()),
]
}
#[inline]
#[must_use]
pub fn irect_edges(rect: &IRect) -> [ILine; 4] {
let min = rect.min;
let max = rect.max;
let width = rect.width();
let height = rect.height();
[
iline(min, min + ivec2(width, 0)),
iline(min + ivec2(width, 0), max),
iline(max, min + ivec2(0, height)),
iline(min + ivec2(0, height), min),
]
}
#[inline]
#[must_use]
pub fn to_cropped_urect(rect: &IRect) -> URect {
URect::from_corners(
rect.min.max(IVec2::ZERO).as_uvec2(),
rect.max.max(IVec2::ZERO).as_uvec2(),
)
}
#[inline]
#[must_use]
pub fn exclusive_irect(rect: &IRect) -> IRect {
if rect.is_empty() {
return *rect;
}
let max = rect.max - IVec2::ONE;
IRect::from_corners(rect.min, max.max(rect.min))
}
#[inline]
#[must_use]
pub fn exclusive_urect(rect: &URect) -> URect {
if rect.is_empty() || rect.max.x == 0 || rect.max.y == 0 {
return *rect;
}
let max = rect.max - UVec2::ONE;
URect::from_corners(rect.min, max.max(rect.min))
}