1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use cgmath::{BaseFloat, InnerSpace, Point2, Transform, Vector2};

use Aabb2;
use line::Line2;
use traits::{ComputeBound, Primitive};

impl<S> Primitive for Line2<S>
where
    S: BaseFloat,
{
    type Point = Point2<S>;

    fn support_point<T>(&self, direction: &Vector2<S>, transform: &T) -> Self::Point
    where
        T: Transform<Self::Point>,
    {
        let direction = transform.inverse_transform_vector(*direction).unwrap();
        let t = direction.dot(self.dest - self.origin);
        if t >= S::zero() {
            transform.transform_point(self.dest)
        } else {
            transform.transform_point(self.origin)
        }
    }
}

impl<S> ComputeBound<Aabb2<S>> for Line2<S>
where
    S: BaseFloat,
{
    fn compute_bound(&self) -> Aabb2<S> {
        Aabb2::new(self.origin, self.dest)
    }
}

#[cfg(test)]
mod tests {

    use super::*;
    use algorithm::minkowski::GJK2;
    use cgmath::{Basis2, Decomposed, Rad, Rotation2};
    use primitive::Rectangle;

    fn transform(x: f32, y: f32, angle: f32) -> Decomposed<Vector2<f32>, Basis2<f32>> {
        Decomposed {
            disp: Vector2::new(x, y),
            rot: Rotation2::from_angle(Rad(angle)),
            scale: 1.,
        }
    }

    #[test]
    fn test_line_rectangle_intersect() {
        let line = Line2::new(Point2::new(0., -1.), Point2::new(0., 1.));
        let rectangle = Rectangle::new(1., 0.2);
        let transform_1 = transform(1., 0., 0.);
        let transform_2 = transform(1.1, 0., 0.);
        let gjk = GJK2::new();
        assert!(
            gjk.intersect(&line, &transform_1, &rectangle, &transform_2)
                .is_some()
        );
    }
}