git.iko.soy/metal-metaballs
on master help sign in
219 lines 4.3 kB history raw
1// TODO: Unite UIView and CALayer extensions under a common protocol
3import UIKit
5func - (left: CGPoint, right: CGPoint) -> CGVector {
6 return CGVector(dx: left.x - right.x, dy: left.y - right.y)
7}
9func * (left: CGVector, right: CGVector) -> CGFloat {
10 return (left.dx * right.dx) + (left.dy * right.dy)
13func / (vector: CGVector, scalar: CGFloat) -> CGVector {
14 return CGVector(dx: vector.dx / scalar, dy: vector.dy / scalar)
17extension CGVector {
18 var norm: CGFloat {
19 get {
20 let dot = self * self
21 return sqrt(dot)
22 }
23 }
25 var normalized: CGVector {
26 get {
27 return self / norm
28 }
29 }
31 mutating func normalize() {
32 let norm = self.norm
33 dx = dx / norm
34 dy = dy / norm
35 }
39extension CGFloat: DoubleValuable {
40 var toDouble: Double { get {
41 return Double(self)
42 }
43 }
45 static func fromDouble(_ double: Double) -> CGFloat {
46 return CGFloat(double)
47 }
51extension CGFloat: Numeric {}
53extension CGRect {
54 var x: CGFloat {
55 get {
56 return origin.x
57 }
58 set {
59 origin.x = newValue
60 }
61 }
63 var y: CGFloat {
64 get {
65 return origin.y
66 }
67 set {
68 origin.y = newValue
69 }
70 }
73extension CGSize {
74 init(_ squareSize: CGFloat) {
75 self.init(width: squareSize, height: squareSize)
76 }
79extension UIView {
80 var origin: CGPoint {
81 get {
82 return frame.origin
83 }
84 set {
85 frame.origin = newValue
86 }
87 }
89 var size: CGSize {
90 get {
91 return frame.size
92 }
93 set {
94 frame.size = newValue
95 }
96 }
98 var width: CGFloat {
99 get {
100 return frame.width
101 }
102 set {
103 frame.size = CGSize(width: newValue, height: height)
104 }
105 }
107 var height: CGFloat {
108 get {
109 return frame.height
110 }
111 set {
112 frame.size = CGSize(width: width, height: newValue)
113 }
114 }
116 var middle: CGPoint {
117 get {
118 return CGPoint(x: origin.x + width / 2, y: origin.y + height / 2)
119 }
120 set {
121 origin = CGPoint(x: newValue.x - width / 2, y: newValue.y - height / 2)
122 }
123 }
125 var midX: CGFloat {
126 get {
127 return middle.x
128 }
129 set {
130 middle = CGPoint(x: newValue, y: midY)
131 }
132 }
134 var midY: CGFloat {
135 get {
136 return middle.y
137 }
138 set {
139 middle = CGPoint(x: midX, y: newValue)
140 }
141 }
144extension CALayer {
145 var origin: CGPoint {
146 get {
147 return frame.origin
148 }
149 set {
150 frame.origin = newValue
151 }
152 }
154 var size: CGSize {
155 get {
156 return frame.size
157 }
158 set {
159 frame.size = newValue
160 }
161 }
163 var width: CGFloat {
164 get {
165 return frame.width
166 }
167 set {
168 frame.size = CGSize(width: newValue, height: height)
169 }
170 }
172 var height: CGFloat {
173 get {
174 return frame.height
175 }
176 set {
177 frame.size = CGSize(width: width, height: newValue)
178 }
179 }
181 var middle: CGPoint {
182 get {
183 return CGPoint(x: origin.x + width / 2, y: origin.y + height / 2)
184 }
185 set {
186 origin = CGPoint(x: newValue.x - width / 2, y: newValue.y - height / 2)
187 }
188 }
190 var midX: CGFloat {
191 get {
192 return middle.x
193 }
194 set {
195 middle = CGPoint(x: newValue, y: midY)
196 }
197 }
199 var midY: CGFloat {
200 get {
201 return middle.y
202 }
203 set {
204 middle = CGPoint(x: midX, y: newValue)
205 }
206 }
209let screenRect = UIScreen.main.bounds
210let screenWidth = screenRect.size.width
211let screenHeight = screenRect.size.height
213func * <T: Numeric>(vector: CGVector, scalar: T) -> CGVector {
214 return CGVector(dx: vector.dx * CGFloat(scalar.toDouble), dy: vector.dy * CGFloat(scalar.toDouble))
217func + (point: CGPoint, vector: CGVector) -> CGPoint {
218 return CGPoint(x: point.x + vector.dx, y: point.y + vector.dy)