rusttype/
geometry.rs

1use core::ops;
2
3/// A point in 2-dimensional space, with each dimension of type `N`.
4///
5/// Legal operations on points are addition and subtraction by vectors, and
6/// subtraction between points, to give a vector representing the offset between
7/// the two points. Combined with the legal operations on vectors, meaningful
8/// manipulations of vectors and points can be performed.
9///
10/// For example, to interpolate between two points by a factor `t`:
11///
12/// ```
13/// # use rusttype::*;
14/// # let t = 0.5; let p0 = point(0.0, 0.0); let p1 = point(0.0, 0.0);
15/// let interpolated_point = p0 + (p1 - p0) * t;
16/// ```
17#[derive(Copy, Clone, Debug, Default, PartialOrd, Ord, PartialEq, Eq, Hash)]
18pub struct Point<N> {
19    pub x: N,
20    pub y: N,
21}
22
23/// A vector in 2-dimensional space, with each dimension of type `N`.
24///
25/// Legal operations on vectors are addition and subtraction by vectors,
26/// addition by points (to give points), and multiplication and division by
27/// scalars.
28#[derive(Copy, Clone, Debug, Default, PartialOrd, Ord, PartialEq, Eq, Hash)]
29pub struct Vector<N> {
30    pub x: N,
31    pub y: N,
32}
33
34/// A convenience function for generating `Point`s.
35#[inline]
36pub fn point<N>(x: N, y: N) -> Point<N> {
37    Point { x, y }
38}
39/// A convenience function for generating `Vector`s.
40#[inline]
41pub fn vector<N>(x: N, y: N) -> Vector<N> {
42    Vector { x, y }
43}
44
45impl<N: ops::Sub<Output = N>> ops::Sub for Point<N> {
46    type Output = Vector<N>;
47    fn sub(self, rhs: Point<N>) -> Vector<N> {
48        vector(self.x - rhs.x, self.y - rhs.y)
49    }
50}
51
52impl<N: ops::Add<Output = N>> ops::Add for Vector<N> {
53    type Output = Vector<N>;
54    fn add(self, rhs: Vector<N>) -> Vector<N> {
55        vector(self.x + rhs.x, self.y + rhs.y)
56    }
57}
58
59impl<N: ops::Sub<Output = N>> ops::Sub for Vector<N> {
60    type Output = Vector<N>;
61    fn sub(self, rhs: Vector<N>) -> Vector<N> {
62        vector(self.x - rhs.x, self.y - rhs.y)
63    }
64}
65
66impl ops::Mul<f32> for Vector<f32> {
67    type Output = Vector<f32>;
68    fn mul(self, rhs: f32) -> Vector<f32> {
69        vector(self.x * rhs, self.y * rhs)
70    }
71}
72
73impl ops::Mul<Vector<f32>> for f32 {
74    type Output = Vector<f32>;
75    fn mul(self, rhs: Vector<f32>) -> Vector<f32> {
76        vector(self * rhs.x, self * rhs.y)
77    }
78}
79
80impl ops::Mul<f64> for Vector<f64> {
81    type Output = Vector<f64>;
82    fn mul(self, rhs: f64) -> Vector<f64> {
83        vector(self.x * rhs, self.y * rhs)
84    }
85}
86
87impl ops::Mul<Vector<f64>> for f64 {
88    type Output = Vector<f64>;
89    fn mul(self, rhs: Vector<f64>) -> Vector<f64> {
90        vector(self * rhs.x, self * rhs.y)
91    }
92}
93
94impl ops::Div<f32> for Vector<f32> {
95    type Output = Vector<f32>;
96    fn div(self, rhs: f32) -> Vector<f32> {
97        vector(self.x / rhs, self.y / rhs)
98    }
99}
100
101impl ops::Div<Vector<f32>> for f32 {
102    type Output = Vector<f32>;
103    fn div(self, rhs: Vector<f32>) -> Vector<f32> {
104        vector(self / rhs.x, self / rhs.y)
105    }
106}
107
108impl ops::Div<f64> for Vector<f64> {
109    type Output = Vector<f64>;
110    fn div(self, rhs: f64) -> Vector<f64> {
111        vector(self.x / rhs, self.y / rhs)
112    }
113}
114
115impl ops::Div<Vector<f64>> for f64 {
116    type Output = Vector<f64>;
117    fn div(self, rhs: Vector<f64>) -> Vector<f64> {
118        vector(self / rhs.x, self / rhs.y)
119    }
120}
121
122impl<N: ops::Add<Output = N>> ops::Add<Vector<N>> for Point<N> {
123    type Output = Point<N>;
124    fn add(self, rhs: Vector<N>) -> Point<N> {
125        point(self.x + rhs.x, self.y + rhs.y)
126    }
127}
128
129impl<N: ops::Sub<Output = N>> ops::Sub<Vector<N>> for Point<N> {
130    type Output = Point<N>;
131    fn sub(self, rhs: Vector<N>) -> Point<N> {
132        point(self.x - rhs.x, self.y - rhs.y)
133    }
134}
135
136impl<N: ops::Add<Output = N>> ops::Add<Point<N>> for Vector<N> {
137    type Output = Point<N>;
138    fn add(self, rhs: Point<N>) -> Point<N> {
139        point(self.x + rhs.x, self.y + rhs.y)
140    }
141}
142
143/// A rectangle, with top-left corner at `min`, and bottom-right corner at
144/// `max`.
145#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
146pub struct Rect<N> {
147    pub min: Point<N>,
148    pub max: Point<N>,
149}
150
151impl<N: ops::Sub<Output = N> + Copy> Rect<N> {
152    pub fn width(&self) -> N {
153        self.max.x - self.min.x
154    }
155    pub fn height(&self) -> N {
156        self.max.y - self.min.y
157    }
158}