#![cfg(feature = "geometry")]
use gemath::*;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ray2_point_at_and_closest_point() {
let r: Ray2<(), ()> = Ray2::new(Vec2::new(1.0, 2.0), Vec2::new(2.0, 0.0));
assert_eq!(r.point_at(0.0), Vec2::new(1.0, 2.0));
assert_eq!(r.point_at(3.0), Vec2::new(7.0, 2.0));
let p = Vec2::new(0.0, 0.0);
assert_eq!(r.closest_point(p), Vec2::new(1.0, 2.0));
assert!((r.distance_to_point(p) - (Vec2::<(), ()>::new(-1.0, -2.0)).length()).abs() < 1e-6);
}
#[test]
fn ray3_point_at_and_closest_point() {
let r: Ray3<(), ()> = Ray3::new(Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 2.0));
assert_eq!(r.point_at(0.5), Vec3::new(0.0, 0.0, 1.0));
let p = Vec3::new(1.0, 0.0, -10.0);
assert_eq!(r.closest_point(p), Vec3::new(0.0, 0.0, 0.0));
}
#[test]
fn segment2_closest_point_distance() {
let s: Segment2<(), ()> = Segment2::new(Vec2::new(0.0, 0.0), Vec2::new(2.0, 0.0));
let p = Vec2::new(1.0, 3.0);
assert_eq!(s.closest_point(p), Vec2::new(1.0, 0.0));
assert!((s.distance_to_point(p) - 3.0).abs() < 1e-6);
assert!((s.length() - 2.0).abs() < 1e-6);
}
#[test]
fn segment3_closest_point_distance() {
let s: Segment3<(), ()> = Segment3::new(Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 2.0));
let p = Vec3::new(0.0, 3.0, 1.0);
assert_eq!(s.closest_point(p), Vec3::new(0.0, 0.0, 1.0));
assert!((s.distance_to_point(p) - 3.0).abs() < 1e-6);
assert!((s.length() - 2.0).abs() < 1e-6);
}
#[test]
fn circle_queries() {
let c: Circle<(), ()> = Circle::new(Vec2::new(0.0, 0.0), 2.0);
assert!(c.contains_point(Vec2::new(0.0, 2.0)));
assert!(!c.contains_point(Vec2::new(0.0, 2.1)));
assert!((c.area() - (core::f32::consts::PI * 4.0)).abs() < 1e-6);
let p = Vec2::new(3.0, 0.0);
assert_eq!(c.closest_point(p), Vec2::new(2.0, 0.0));
assert!((c.distance_to_point(p) - 1.0).abs() < 1e-6);
}
#[test]
fn sphere_queries() {
let s: Sphere<(), ()> = Sphere::new(Vec3::new(0.0, 0.0, 0.0), 2.0);
assert!(s.contains_point(Vec3::new(0.0, 0.0, 2.0)));
assert!(!s.contains_point(Vec3::new(0.0, 0.0, 2.1)));
assert!((s.volume() - ((4.0 / 3.0) * core::f32::consts::PI * 8.0)).abs() < 1e-5);
let p = Vec3::new(0.0, 0.0, 3.0);
assert_eq!(s.closest_point(p), Vec3::new(0.0, 0.0, 2.0));
assert!((s.distance_to_point(p) - 1.0).abs() < 1e-6);
}
#[test]
fn plane_signed_distance_and_project() {
let plane: Plane<(), ()> = Plane::from_point_normal(Vec3::new(0.0, 0.0, 5.0), Vec3::new(0.0, 0.0, 1.0)).unwrap();
let p_above = Vec3::new(0.0, 0.0, 7.0);
let p_below = Vec3::new(0.0, 0.0, 4.0);
assert!((plane.signed_distance_to_point(p_above) - 2.0).abs() < 1e-6);
assert!((plane.signed_distance_to_point(p_below) + 1.0).abs() < 1e-6);
let proj = plane.project_point(p_above);
assert!((proj - Vec3::new(0.0, 0.0, 5.0)).length() < 1e-6);
}
#[test]
fn capsule2_queries() {
let cap: Capsule2<(), ()> = Capsule2::new(Vec2::new(0.0, 0.0), Vec2::new(2.0, 0.0), 1.0);
assert!(cap.contains_point(Vec2::new(1.0, 0.5)));
assert!(!cap.contains_point(Vec2::new(1.0, 1.01)));
assert!((cap.distance_to_point(Vec2::new(1.0, 2.0)) - 1.0).abs() < 1e-6);
let cp = cap.closest_point(Vec2::new(1.0, 2.0));
assert!((cap.segment().distance_to_point(cp) - 1.0).abs() < 1e-5);
}
#[test]
fn capsule3_queries() {
let cap: Capsule3<(), ()> = Capsule3::new(Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 2.0), 1.0);
assert!(cap.contains_point(Vec3::new(0.5, 0.0, 1.0)));
assert!(!cap.contains_point(Vec3::new(1.01, 0.0, 1.0)));
assert!((cap.distance_to_point(Vec3::new(0.0, 3.0, 1.0)) - 2.0).abs() < 1e-6);
let cp = cap.closest_point(Vec3::new(0.0, 3.0, 1.0));
assert!((cap.segment().distance_to_point(cp) - 1.0).abs() < 1e-5);
}
}