Add Ray2<>Aabb2 intersection impl
This commit is contained in:
parent
814b845de7
commit
4f17d73f23
2 changed files with 63 additions and 2 deletions
49
src/aabb.rs
49
src/aabb.rs
|
@ -22,9 +22,11 @@
|
|||
|
||||
use point::{Point, Point2, Point3};
|
||||
use vector::{Vector, Vector2, Vector3};
|
||||
use num::BaseNum;
|
||||
use ray::{Ray2};
|
||||
use intersect::Intersect;
|
||||
use num::{BaseNum, BaseFloat};
|
||||
use std::fmt;
|
||||
use std::num::{zero, one};
|
||||
use std::num::{zero, one, Float};
|
||||
|
||||
pub trait Aabb<S: BaseNum, V: Vector<S>, P: Point<S, V>> {
|
||||
/// Create a new AABB using two points as opposing corners.
|
||||
|
@ -172,3 +174,46 @@ impl<S: BaseNum> fmt::Show for Aabb3<S> {
|
|||
write!(f, "[{} - {}]", self.min, self.max)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> Intersect<Option<Point2<S>>> for (Ray2<S>, Aabb2<S>) {
|
||||
fn intersection(&self) -> Option<Point2<S>> {
|
||||
match *self {
|
||||
(ref ray, ref aabb) => {
|
||||
|
||||
let mut tmin: S = Float::neg_infinity();
|
||||
let mut tmax: S = Float::infinity();
|
||||
|
||||
if ray.direction.x != zero() {
|
||||
let tx1 = (aabb.min.x - ray.origin.x) / ray.direction.x;
|
||||
let tx2 = (aabb.max.x - ray.origin.x) / ray.direction.x;
|
||||
tmin = tmin.max(tx1.min(tx2));
|
||||
tmax = tmax.min(tx1.max(tx2));
|
||||
}
|
||||
|
||||
if ray.direction.y != zero() {
|
||||
let ty1 = (aabb.min.y - ray.origin.y) / ray.direction.y;
|
||||
let ty2 = (aabb.max.y - ray.origin.y) / ray.direction.y;
|
||||
tmin = tmin.max(ty1.min(ty2));
|
||||
tmax = tmax.min(ty1.max(ty2));
|
||||
}
|
||||
|
||||
if tmin < zero() && tmax < zero() {
|
||||
None
|
||||
}
|
||||
else if tmax >= tmin {
|
||||
if tmin >= zero() {
|
||||
Some(Point2::new(ray.origin.x + ray.direction.x * tmin,
|
||||
ray.origin.y + ray.direction.y * tmin))
|
||||
}
|
||||
else {
|
||||
Some(Point2::new(ray.origin.x + ray.direction.x * tmax,
|
||||
ray.origin.y + ray.direction.y * tmax))
|
||||
}
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ extern crate cgmath;
|
|||
use cgmath::aabb::*;
|
||||
use cgmath::point::{Point2, Point3};
|
||||
use cgmath::vector::{Vector2, Vector3};
|
||||
use cgmath::ray::{Ray};
|
||||
use cgmath::intersect::Intersect;
|
||||
|
||||
#[test]
|
||||
fn test_aabb() {
|
||||
|
@ -64,3 +66,17 @@ fn test_aabb() {
|
|||
assert_eq!(aabb.mul_v(&Vector3::new(1i, 2i, 3i)),
|
||||
Aabb3::new(Point3::new(-20i, -20i, -15i), Point3::new(10i, 60i, 15i)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_aabb_ray_intersect() {
|
||||
let aabb = Aabb2::new(Point2::new(-5.0f32, 5.0), Point2::new(5.0, 10.0));
|
||||
let ray1 = Ray::new(Point2::new(0.0f32, 0.0), Vector2::new(0.0, 1.0));
|
||||
let ray2 = Ray::new(Point2::new(-10.0f32, 0.0), Vector2::new(2.5, 1.0));
|
||||
let ray3 = Ray::new(Point2::new(0.0f32, 0.0), Vector2::new(-1.0, -1.0));
|
||||
let ray4 = Ray::new(Point2::new(3.0f32, 7.0), Vector2::new(1.0, 1.0));
|
||||
|
||||
assert_eq!((ray1, aabb).intersection(), Some(Point2::new(0.0, 5.0)));
|
||||
assert_eq!((ray2, aabb).intersection(), Some(Point2::new(2.5, 5.0)));
|
||||
assert_eq!((ray3, aabb).intersection(), None);
|
||||
assert_eq!((ray4, aabb).intersection(), Some(Point2::new(5.0, 9.0)));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue