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
use na::*;
use num::Float;
use alga::general::{SupersetOf,SubsetOf};

#[derive(Clone,Copy,Debug,PartialEq)]
pub struct Rect<T: BaseNum>{
    pub pos: Pnt2<T>,
    pub width: T,
    pub height: T
}

pub trait InsideRect<T: BaseNum>{
    fn inside(&self, rect: &Rect<T>) -> bool;
}

impl<T:Float + BaseNum> InsideRect<T> for Pnt2<T>{
    fn inside(&self, rect: &Rect<T>) -> bool{
        self.x > rect.pos.x && self.y > rect.pos.y && self.x < rect.pos.x + rect.width && self.y < rect.pos.y + rect.height
    }
}

impl<N1:BaseNum, N2:BaseNum + SupersetOf<N1>> SubsetOf<Rect<N2>> for Rect<N1>
    where Pnt2<N2>: SupersetOf<Pnt2<N1>>{
    fn is_in_subset(t: &Rect<N2>) -> bool{
        t.pos.is_in_subset() && t.width.is_in_subset() && t.height.is_in_subset()
    }

    unsafe fn from_superset_unchecked(t: &Rect<N2>) -> Rect<N1>{
        Rect{
            pos: t.pos.to_subset_unchecked(),
            width: t.width.to_subset_unchecked(),
            height: t.height.to_subset_unchecked(),
        }
    }

    fn to_superset(&self) -> Rect<N2>{
        Rect{
            pos: self.pos.to_superset(),
            width: convert(self.width),
            height: convert(self.height),
        }
    }
}

impl<T: Float + BaseNum> Rect<T>{
    pub fn aspect_ratio(&self) -> T{
        self.width / self.height
    }

    pub fn min_x(&self) -> T {
        self.pos.x.min(self.pos.x + self.width)
    }

    pub fn max_x(&self) -> T {
        self.pos.x.max(self.pos.x + self.width)
    }

    pub fn min_y(&self) -> T {
        self.pos.y.min(self.pos.y + self.height)
    }

    pub fn max_y(&self) -> T {
        self.pos.y.max(self.pos.y + self.height)
    }
}


impl<T: BaseNum> Rect<T>{
    pub fn top_left(&self) -> Pnt2<T>{
        self.pos
    }

    pub fn top_right(&self) -> Pnt2<T>{
        pnt2(self.pos.x + self.width, self.pos.y)
    }

    pub fn bottom_left(&self) -> Pnt2<T>{
        pnt2(self.pos.x, self.pos.y + self.height)
    }

    pub fn bottom_right(&self) -> Pnt2<T>{
        pnt2(self.pos.x + self.width, self.pos.y + self.height)
    }

    pub fn center(&self) -> Pnt2<T> where i32: SubsetOf<T>{
        let two: T = convert(2);
        pnt2(self.pos.x + self.width, self.pos.y + self.height) / two
    }
}