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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use crate::intersection::shared::{
    ellipse_circle, line_ellipse, lines_lines, polygon_ellipse, rect_ellipse, triangle_ellipse,
};
use crate::prelude::*;

impl IntersectsShape for Ellipse {
    fn intersects_rect(&self, rect: &Rect) -> bool {
        rect_ellipse(rect, self)
    }

    fn intersects_circle(&self, circle: &Circle) -> bool {
        ellipse_circle(self, circle)
    }

    fn intersects_line(&self, line: &Line) -> bool {
        line_ellipse(line, self)
    }

    fn intersects_triangle(&self, triangle: &Triangle) -> bool {
        triangle_ellipse(triangle, self)
    }

    fn intersects_ellipse(&self, ellipse: &Ellipse) -> bool {
        lines_lines(
            &self.as_polygon().as_lines(),
            &ellipse.as_polygon().as_lines(),
        )
    }

    fn intersects_polygon(&self, polygon: &Polygon) -> bool {
        polygon_ellipse(polygon, self)
    }
}

#[cfg(test)]
mod test {
    use crate::prelude::*;

    #[test]
    fn line_below_ellipse_at_zero() {
        let line = Line::new((6, 47), (26, 67));
        let ellipse = Ellipse::new((1, 2), 124, 78);
        assert!(!line.intersects_ellipse(&ellipse));
        assert!(!ellipse.intersects_line(&line));
    }

    #[test]
    fn line_intersecting_ellipse_at_zero() {
        let line = Line::new((15, 30), (35, 50));
        let ellipse = Ellipse::new((1, 2), 124, 78);
        assert!(line.intersects_ellipse(&ellipse));
        assert!(ellipse.intersects_line(&line));
    }

    #[test]
    fn line_inside_ellipse_at_zero() {
        let line = Line::new((7, 4), (27, 24));
        let ellipse = Ellipse::new((1, 2), 124, 78);
        assert!(!line.intersects_ellipse(&ellipse));
        assert!(!ellipse.intersects_line(&line));
    }

    #[test]
    fn line_inside_ellipse() {
        let line = Line::new((101, 119), (121, 139));
        let ellipse = Ellipse::new((111, 129), 82, 52);
        assert!(!line.intersects_ellipse(&ellipse));
        assert!(!ellipse.intersects_line(&line));
    }

    #[test]
    fn line_above_ellipse() {
        let line = Line::new((97, 57), (117, 77));
        let ellipse = Ellipse::new((111, 129), 82, 52);
        assert!(!line.intersects_ellipse(&ellipse));
        assert!(!ellipse.intersects_line(&line));
    }

    #[test]
    fn line_intersecting_ellipse() {
        let line = Line::new((105, 145), (125, 165));
        let ellipse = Ellipse::new((111, 129), 82, 52);
        assert!(line.intersects_ellipse(&ellipse));
        assert!(ellipse.intersects_line(&line));
    }

    #[test]
    fn line_inside_rotated_ellipse() {
        let line = Line::new((114, 90), (134, 110));
        let ellipse = Ellipse::new((147, 131), 120, 80).rotate(48);
        assert!(!line.intersects_ellipse(&ellipse));
        assert!(!ellipse.intersects_line(&line));
    }

    #[test]
    fn line_left_of_rotated_ellipse() {
        let line = Line::new((91, 145), (111, 165));
        let ellipse = Ellipse::new((147, 131), 120, 80).rotate(48);
        assert!(!line.intersects_ellipse(&ellipse));
        assert!(!ellipse.intersects_line(&line));
    }

    #[test]
    fn line_intersecting_rotated_ellipse() {
        let line = Line::new((167, 172), (187, 192));
        let ellipse = Ellipse::new((147, 131), 120, 80).rotate(48);
        assert!(line.intersects_ellipse(&ellipse));
        assert!(ellipse.intersects_line(&line));
    }
}