use super::*;
#[test]
fn test_collinear_points() {
let pt1 = Point3(0.0, 0.0, 0.0);
let pt2 = Point3(1.0, 1.0, 1.0);
let pt3 = Point3(2.0, 2.0, 2.0);
let plane = Plane3::triangle(pt1, pt2, pt3);
assert_eq!(plane.normal, Vec3(0.0, 0.0, 0.0));
assert_eq!(plane.distance, 0.0);
}
#[test]
fn test_trace() {
let plane = Plane3(Vec3(0.0, 0.0, 1.0), 0.0);
let ray = Ray3 {
origin: Point3(0.0, 0.0, -5.0),
direction: Vec3(0.0, 0.0, 1.0),
distance: Interval(0.0, f64::INFINITY),
};
let inside = ray.inside(&plane);
assert_eq!(inside, false);
let result = ray.trace(&plane);
assert!(result.is_some());
}
#[test]
fn test_trace_both_sides() {
#[track_caller]
fn check(dir: f64, pt: f64, success: bool) {
let plane = Plane3(Vec3::Z, 0.0);
let ray = Ray3 {
origin: Point3(0.0, 0.0, pt),
direction: Vec3(0.0, 0.0, dir),
distance: Interval(0.0, f64::INFINITY),
};
let result = ray.trace(&plane);
if success {
assert!(result.is_some());
assert_eq!(result.unwrap().distance, pt.abs());
assert_eq!(result.unwrap().normal.abs(), plane.normal.abs());
}
else {
assert!(result.is_none());
}
}
check( 1.0, -2.0, true);
check(-1.0, 2.0, true);
check( 1.0, 2.0, false);
check(-1.0, -2.0, false);
}
#[test]
fn test_trace_on_plane() {
let plane = Plane3(Vec3(0.0, 0.0, 1.0), 0.0);
let ray = Ray3 {
origin: Point3(0.0, 0.0, 0.0),
direction: Vec3(0.0, 0.0, 1.0),
distance: Interval(0.0, f64::INFINITY),
};
let inside = ray.inside(&plane);
assert_eq!(inside, true);
let result = ray.trace(&plane);
assert!(result.is_none()); }
#[test]
fn test_trace_random_planes() {
let mut rng = urandom::new();
for _ in 0..1000 {
let normal = Vec3(rng.next_f32(), rng.next_f32(), rng.next_f32()).norm();
let distance = rng.next_f32() * 10.0;
let plane = Plane3(normal, -distance);
let origin = normal * (distance + rng.next_f32());
let direction = (normal + Vec3(rng.range(-0.5..0.5), rng.range(-0.5..0.5), rng.range(-0.5..0.5))).norm();
let mut ray = Ray3 { origin, direction, distance: Interval(0.0, f32::INFINITY) };
let hit = ray.trace(&plane);
assert!(hit.is_none(), "Ray should not hit the plane when moving away from it");
ray.direction = -ray.direction;
let hit = ray.trace(&plane).expect("Ray should hit the plane when moving towards it");
let d = plane.distance(hit.point);
assert!(d.abs() < 1e-4, "Hit point should be on the plane: {d}");
}
}