@@ -8,6 +8,8 @@ public struct Pair<T,U> {
8
8
self . y = y
9
9
}
10
10
}
11
+ extension Pair : Equatable where T: Equatable , U: Equatable { }
12
+ extension Pair : Hashable where T: Hashable , U: Hashable { }
11
13
12
14
public typealias Point = Pair < Float , Float >
13
15
@@ -19,7 +21,7 @@ public func + (lhs: Point, rhs: Point) -> Point {
19
21
return Point ( lhs. x + rhs. x, lhs. y + rhs. y)
20
22
}
21
23
22
- public struct Size {
24
+ public struct Size : Hashable {
23
25
public var width : Float
24
26
public var height : Float
25
27
@@ -34,7 +36,7 @@ extension Size {
34
36
35
37
/// A Rectangle in a bottom-left coordinate space.
36
38
///
37
- public struct Rect {
39
+ public struct Rect : Hashable {
38
40
public var origin : Point
39
41
public var size : Size
40
42
@@ -54,6 +56,8 @@ extension Rect {
54
56
return Rect ( origin: normalizedOrigin, size: normalizedSize)
55
57
}
56
58
59
+ // Coordinate accessors.
60
+
57
61
public var minX : Float {
58
62
return normalized. origin. x
59
63
}
@@ -79,22 +83,64 @@ extension Rect {
79
83
let norm = normalized
80
84
return norm. origin. y + norm. size. height
81
85
}
82
-
83
- public var width : Float {
84
- return size. width
85
- }
86
-
87
- public var height : Float {
88
- return size. height
86
+
87
+ public var center : Point {
88
+ return Point ( midX, midY)
89
89
}
90
-
90
+
91
91
public init ( size: Size , centeredOn center: Point ) {
92
92
self = Rect (
93
93
origin: Point ( center. x - size. width/ 2 , center. y - size. height/ 2 ) ,
94
94
size: size
95
95
)
96
96
}
97
+
98
+ // Size accessors.
99
+
100
+ public var width : Float {
101
+ get { return size. width }
102
+ set { size. width = newValue }
103
+ }
97
104
105
+ public var height : Float {
106
+ get { return size. height }
107
+ set { size. height = newValue }
108
+ }
109
+
110
+ // Rounding.
111
+
112
+ /// Returns a version of this `Rect` rounded by `roundOutwards`
113
+ public var roundedOutwards : Rect {
114
+ var rect = self
115
+ rect. roundOutwards ( )
116
+ return rect
117
+ }
118
+
119
+ /// Rounds this `Rect` to integer coordinates, by rounding all points away from the center.
120
+ public mutating func roundOutwards( ) {
121
+ origin. x. round ( . down)
122
+ origin. y. round ( . down)
123
+ size. width. round ( . up)
124
+ size. height. round ( . up)
125
+ }
126
+
127
+ /// Returns a version of this `Rect` rounded by `roundInwards`
128
+ public var roundedInwards : Rect {
129
+ var rect = self
130
+ rect. roundInwards ( )
131
+ return rect
132
+ }
133
+
134
+ /// Rounds this `Rect` to integer coordinates, by rounding all points towards the center.
135
+ public mutating func roundInwards( ) {
136
+ origin. x. round ( . up)
137
+ origin. y. round ( . up)
138
+ size. width. round ( . down)
139
+ size. width. round ( . down)
140
+ }
141
+
142
+ // Subtraction operations.
143
+
98
144
mutating func contract( by distance: Float ) {
99
145
origin. x += distance
100
146
origin. y += distance
@@ -108,4 +154,22 @@ extension Rect {
108
154
size. width -= dx
109
155
size. height -= dy
110
156
}
157
+
158
+ // Other Utilities.
159
+
160
+ /// The range of Y coordinates considered inside this `Rect`.
161
+ /// If a coordinate `y` is inside this Range, it means that `minY < y < maxY`,
162
+ /// - i.e., it is _within_ and not _on_ the bounds of the `Rect`.
163
+ internal var internalYCoordinates : Range < Float > {
164
+ let norm = normalized
165
+ return norm. origin. y. nextUp..< norm. origin. y. nextUp + norm. size. height
166
+ }
167
+
168
+ /// The range of X coordinates considered inside this `Rect`.
169
+ /// If a coordinate `x` is inside this Range, it means that `minX < x < maxX`
170
+ /// - i.e., it is _within_ and not _on_ the bounds of the `Rect`
171
+ internal var internalXCoordinates : Range < Float > {
172
+ let norm = normalized
173
+ return norm. origin. x. nextUp..< norm. origin. x. nextUp + norm. size. width
174
+ }
111
175
}
0 commit comments