#![cfg(all(feature = "rect2", feature = "mat4"))]
use gemath::*;
use crate::vec2::*;
use crate::rect2::*;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rect2_new() {
let r: Rect2<(),()> = Rect2::new(Vec2::new(1.0, 2.0), Vec2::new(3.0, 4.0));
assert_eq!(r.pos, Vec2::new(1.0, 2.0));
assert_eq!(r.dim, Vec2::new(3.0, 4.0));
}
#[test]
fn test_rect2_default() {
let r: Rect2 = Default::default();
assert_eq!(r.pos, Vec2::ZERO);
assert_eq!(r.dim, Vec2::ZERO);
}
#[test]
fn test_rect2_from_slice() {
let r: Rect2<(),()> = Rect2::from_slice(&[1.0, 2.0, 3.0, 4.0]);
assert_eq!(r.pos, Vec2::new(1.0, 2.0));
assert_eq!(r.dim, Vec2::new(3.0, 4.0));
}
#[test]
fn test_rect2_contains_point_coords() {
let r: Rect2<(),()> = Rect2::new(Vec2::new(1.0, 1.0), Vec2::new(3.0, 3.0));
assert!(r.contains_point_coords(2.0, 2.0));
assert!(r.contains_point_coords(1.0, 1.0));
assert!(r.contains_point_coords(1.0, 2.5));
assert!(r.contains_point_coords(2.5, 1.0));
assert!(!r.contains_point_coords(4.0, 4.0));
assert!(!r.contains_point_coords(1.0, 4.0));
assert!(!r.contains_point_coords(4.0, 1.0));
assert!(!r.contains_point_coords(0.0, 0.0));
assert!(!r.contains_point_coords(5.0, 5.0));
let r_neg_dim: Rect2<(),()> = Rect2::new(Vec2::new(4.0, 4.0), Vec2::new(-3.0, -3.0));
assert!(r_neg_dim.contains_point_coords(2.0, 2.0));
assert!(r_neg_dim.contains_point_coords(1.0, 1.0)); assert!(!r_neg_dim.contains_point_coords(4.0, 4.0)); }
#[test]
fn test_rect2_contains_point() {
let r: Rect2<(),()> = Rect2::new(Vec2::new(1.0, 1.0), Vec2::new(3.0, 3.0));
assert!(r.contains_point(Vec2::new(2.0, 2.0)));
assert!(!r.contains_point(Vec2::new(5.0, 5.0)));
}
#[test]
fn test_rect2_intersects_and_intersection() {
let r1: Rect2<(),()> = Rect2::new(Vec2::new(0.0, 0.0), Vec2::new(2.0, 2.0));
let r2: Rect2<(),()> = Rect2::new(Vec2::new(1.0, 1.0), Vec2::new(2.0, 2.0));
let r3: Rect2<(),()> = Rect2::new(Vec2::new(3.0, 3.0), Vec2::new(1.0, 1.0));
let r4: Rect2<(),()> = Rect2::new(Vec2::new(0.5, 0.5), Vec2::new(1.0, 1.0));
assert!(r1.intersects(&r2));
assert_eq!(
r1.intersection(&r2),
Some(Rect2::new(Vec2::new(1.0, 1.0), Vec2::new(1.0, 1.0)))
);
assert!(!r1.intersects(&r3));
assert_eq!(r1.intersection(&r3), None);
assert!(r1.intersects(&r4));
assert_eq!(r1.intersection(&r4), Some(r4));
assert!(r4.intersects(&r1));
assert_eq!(r4.intersection(&r1), Some(r4));
let r_touch_x = Rect2::new(Vec2::new(2.0, 0.0), Vec2::new(1.0, 2.0)); assert!(!r1.intersects(&r_touch_x));
assert_eq!(r1.intersection(&r_touch_x), None);
let r_touch_y = Rect2::new(Vec2::new(0.0, 2.0), Vec2::new(2.0, 1.0)); assert!(!r1.intersects(&r_touch_y));
assert_eq!(r1.intersection(&r_touch_y), None);
let r_neg_dim1: Rect2<(),()> = Rect2::new(Vec2::new(2.0, 2.0), Vec2::new(-2.0, -2.0)); let r_neg_dim2: Rect2<(),()> = Rect2::new(Vec2::new(3.0, 3.0), Vec2::new(-2.0, -2.0)); assert!(r_neg_dim1.intersects(&r_neg_dim2));
assert_eq!(
r_neg_dim1.intersection(&r_neg_dim2),
Some(Rect2::new(Vec2::new(1.0, 1.0), Vec2::new(1.0, 1.0)))
);
let r5: Rect2<(),()> = Rect2::new(Vec2::new(0.0, 0.0), Vec2::new(1.0, 1.0));
let r6: Rect2<(),()> = Rect2::new(Vec2::new(1.0, 1.0), Vec2::new(1.0, 1.0)); assert!(!r5.intersects(&r6));
assert_eq!(r5.intersection(&r6), None);
}
#[test]
fn test_rect2_min_max_size() {
let r: Rect2<(),()> = Rect2::new(Vec2::new(3.0, 2.0), Vec2::new(-2.0, 5.0));
assert_eq!(r.min(), Vec2::new(1.0, 2.0));
assert_eq!(r.max(), Vec2::new(3.0, 7.0));
assert_eq!(r.size(), Vec2::new(2.0, 5.0));
}
#[test]
fn test_rect2_area() {
let r: Rect2<(),()> = Rect2::new(Vec2::new(0.0, 0.0), Vec2::new(3.0, 4.0));
assert_eq!(r.area(), 12.0);
let r_neg: Rect2<(),()> = Rect2::new(Vec2::new(0.0, 0.0), Vec2::new(-3.0, 4.0));
assert_eq!(r_neg.area(), 12.0);
}
#[test]
fn test_rect2_is_empty() {
let r: Rect2<(),()> = Rect2::new(Vec2::new(0.0, 0.0), Vec2::new(0.0, 4.0));
assert!(r.is_empty());
let r2: Rect2<(),()> = Rect2::new(Vec2::new(0.0, 0.0), Vec2::new(3.0, 0.0));
assert!(r2.is_empty());
let r3: Rect2<(),()> = Rect2::new(Vec2::new(0.0, 0.0), Vec2::new(3.0, 4.0));
assert!(!r3.is_empty());
}
#[test]
fn test_rect2_from_min_max() {
let min: Vec2<(),()> = Vec2::new(1.0, 2.0);
let max: Vec2<(),()> = Vec2::new(4.0, 6.0);
let r: Rect2<(),()> = Rect2::from_min_max(min, max);
assert_eq!(r.min(), min);
assert_eq!(r.max(), max);
}
#[test]
fn test_rect2_expand_to_include() {
let r: Rect2<(),()> = Rect2::from_min_max(Vec2::new(1.0, 2.0), Vec2::new(3.0, 4.0));
let expanded: Rect2<(),()> = r.expand_to_include(Vec2::new(5.0, 0.0));
assert_eq!(expanded.min(), Vec2::new(1.0, 0.0));
assert_eq!(expanded.max(), Vec2::new(5.0, 4.0));
}
#[test]
fn test_rect2_union() {
let a: Rect2<(),()> = Rect2::from_min_max(Vec2::new(0.0, 0.0), Vec2::new(2.0, 2.0));
let b: Rect2<(),()> = Rect2::from_min_max(Vec2::new(1.0, -1.0), Vec2::new(3.0, 1.0));
let u: Rect2<(),()> = a.union(&b);
assert_eq!(u.min(), Vec2::new(0.0, -1.0));
assert_eq!(u.max(), Vec2::new(3.0, 2.0));
}
#[test]
fn test_rect2_closest_point_and_distance() {
let rect: Rect2<(),()> = Rect2::from_min_max(Vec2::new(1.0, 1.0), Vec2::new(3.0, 4.0));
assert_eq!(rect.closest_point(Vec2::new(2.0, 2.0)), Vec2::new(2.0, 2.0));
assert_eq!(rect.distance(Vec2::new(2.0, 2.0)), 0.0);
assert_eq!(rect.closest_point(Vec2::new(0.0, 0.0)), Vec2::new(1.0, 1.0));
assert!((rect.distance(Vec2::new(0.0, 0.0)) - (2.0_f32).sqrt()).abs() < 1e-6);
assert_eq!(rect.closest_point(Vec2::new(4.0, 5.0)), Vec2::new(3.0, 4.0));
}
#[test]
fn test_rect2_intersect_ray() {
let rect: Rect2<(),()> = Rect2::from_min_max(Vec2::new(1.0, 1.0), Vec2::new(3.0, 4.0));
let t = rect.intersect_ray(Vec2::new(0.0, 2.0), Vec2::new(1.0, 0.0));
assert!(t.is_some() && (t.unwrap() - 1.0).abs() < 1e-6);
let t2 = rect.intersect_ray(Vec2::new(2.0, 2.0), Vec2::new(1.0, 0.0));
assert!(t2.is_some() && (t2.unwrap() - 1.0).abs() < 1e-6);
let t3 = rect.intersect_ray(Vec2::new(0.0, 0.0), Vec2::new(-1.0, 0.0));
assert!(t3.is_none());
}
#[test]
fn test_rect2_transform() {
use crate::mat4::Mat4;
let rect: Rect2<(),()> = Rect2::from_min_max(Vec2::new(1.0, 2.0), Vec2::new(3.0, 4.0));
let m: Mat4 = Mat4::from_translation(crate::vec3::Vec3::new(10.0, 20.0, 0.0));
let t: Rect2<(),()> = rect.transform(&m);
assert_eq!(t.min(), Vec2::new(11.0, 22.0));
assert_eq!(t.max(), Vec2::new(13.0, 24.0));
}
}
const _CONST_RECT0: Rect2f32 = Rect2f32::new(Vec2f32::new(1.0, 2.0), Vec2f32::new(3.0, 4.0));
const _CONST_RECT1: Rect2f32 = Rect2f32::new(Vec2f32::new(5.0, 6.0), Vec2f32::new(7.0, 8.0));
const _CONST_RECT_FROM_ARRAY: Rect2f32 = Rect2f32::from_array([1.0, 2.0, 3.0, 4.0]);
const _CONST_RECT_MIN: Vec2f32 = _CONST_RECT0.min();
const _CONST_RECT_MAX: Vec2f32 = _CONST_RECT0.max();
const _CONST_RECT_METERS: Rect2Meters = Rect2Meters::new(Vec2Meters::new(1.0, 2.0), Vec2Meters::new(3.0, 4.0));
const _CONST_RECT_WORLD: Rect2World = Rect2World::new(Vec2World::new(1.0, 2.0), Vec2World::new(3.0, 4.0));
const _: () = {
assert!(_CONST_RECT0.pos.x == 1.0 && _CONST_RECT0.pos.y == 2.0);
assert!(_CONST_RECT0.dim.x == 3.0 && _CONST_RECT0.dim.y == 4.0);
assert!(_CONST_RECT_FROM_ARRAY.pos.x == 1.0 && _CONST_RECT_FROM_ARRAY.pos.y == 2.0);
assert!(_CONST_RECT_FROM_ARRAY.dim.x == 3.0 && _CONST_RECT_FROM_ARRAY.dim.y == 4.0);
assert!(_CONST_RECT_MIN.x == 1.0 && _CONST_RECT_MIN.y == 2.0);
assert!(_CONST_RECT_MAX.x == 4.0 && _CONST_RECT_MAX.y == 6.0);
};
#[test]
fn test_rect2_meters_to_pixels() {
let meters: Rect2Meters = Rect2Meters::new(Vec2Meters::new(2.0, 3.0), Vec2Meters::new(4.0, 5.0));
let pixels = meters.to_pixels(100.0);
assert_eq!(pixels.pos, Vec2Pixels::new(200.0, 300.0));
assert_eq!(pixels.dim, Vec2Pixels::new(400.0, 500.0));
}