Advertisement
Guest User

Untitled

a guest
Oct 17th, 2019
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.76 KB | None | 0 0
  1. typealias GeometricValue = Numeric & Comparable
  2.  
  3. struct GenericPoint<ValueType: GeometricValue>: Equatable {
  4. var x: ValueType
  5. var y: ValueType
  6.  
  7. static var zero: Self { Self(x: 0, y: 0) }
  8. }
  9.  
  10. extension GenericPoint {
  11. init(_ x: ValueType, _ y: ValueType) {
  12. self.init(x: x, y: y)
  13. }
  14.  
  15. static func +(lhs: Self, rhs: Self) -> Self {
  16. Self(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
  17. }
  18.  
  19. static func +=(lhs: inout Self, rhs: Self) {
  20. lhs = lhs + rhs
  21. }
  22.  
  23. static func -(lhs: Self, rhs: Self) -> Self {
  24. lhs + (rhs * -1)
  25. }
  26.  
  27. static func -=(lhs: inout Self, rhs: Self) {
  28. lhs = lhs - rhs
  29. }
  30.  
  31. static func *(lhs: Self, scale: ValueType) -> Self {
  32. Self(x: lhs.x * scale, y: lhs.y * scale)
  33. }
  34.  
  35. static func *=(lhs: inout Self, scale: ValueType) {
  36. lhs = lhs * scale
  37. }
  38.  
  39. static prefix func - (point: Self) -> Self {
  40. point * -1
  41. }
  42.  
  43. func offsetBy(dx: ValueType = 0, dy: ValueType = 0) -> Self {
  44. self + Self(x: dx, y: dy)
  45. }
  46. }
  47.  
  48. extension GenericPoint where ValueType: FloatingPoint {
  49. static func /(lhs: Self, scale: ValueType) -> Self {
  50. lhs * (1 / scale)
  51. }
  52.  
  53. static func /=(lhs: inout Self, scale: ValueType) {
  54. lhs *= (1 / scale)
  55. }
  56. }
  57.  
  58. struct GenericSize<ValueType: GeometricValue>: Equatable {
  59. var width: ValueType
  60. var height: ValueType
  61.  
  62. static var zero: Self { Self(width: 0, height: 0) }
  63. }
  64.  
  65. extension GenericSize {
  66. init(_ w: ValueType, _ h: ValueType) {
  67. self.init(width: w, height: h)
  68. }
  69. }
  70.  
  71. extension GenericSize: Sequence where ValueType: Strideable {
  72. typealias Element = GenericPoint<ValueType>
  73.  
  74. func makeIterator() -> AnyIterator<Element> {
  75. return GenericRect(origin: .zero, size: self).makeIterator()
  76. }
  77. }
  78.  
  79. struct GenericRect<ValueType: GeometricValue>: Equatable {
  80. typealias PointType = GenericPoint<ValueType>
  81. typealias SizeType = GenericSize<ValueType>
  82.  
  83. var origin: PointType
  84. var size: SizeType
  85.  
  86. var x: ValueType {
  87. get { origin.x }
  88. set { origin.x = newValue }
  89. }
  90.  
  91. var y: ValueType {
  92. get { origin.y }
  93. set { origin.y = newValue }
  94. }
  95.  
  96. var width: ValueType {
  97. get { size.width }
  98. set { size.width = newValue }
  99. }
  100.  
  101. var height: ValueType {
  102. get { size.height }
  103. set { size.height = newValue }
  104. }
  105.  
  106. var maxX: ValueType { Swift.max(x, x + width) }
  107. var maxY: ValueType { Swift.max(y, y + height) }
  108.  
  109. var minX: ValueType { Swift.min(x, x + width) }
  110. var minY: ValueType { Swift.min(y, y + height) }
  111.  
  112. var bottomLeft: PointType { PointType(x: minX, y: maxY) }
  113. var bottomRight: PointType { PointType(x: maxX, y: maxY) }
  114.  
  115. var area: ValueType {
  116. let copy = standardized()
  117. return copy.width * copy.height
  118. }
  119.  
  120. func contains(_ point: PointType) -> Bool {
  121. let test = standardized()
  122. return point.x >= test.x && point.y >= test.y && point.x < test.x + test.width && point.y < test.y + test.height
  123. }
  124.  
  125. mutating func standardize() {
  126. if width < 0 {
  127. x += width
  128. width *= -1
  129. }
  130.  
  131. if height < 0 {
  132. y += height
  133. height *= -1
  134. }
  135. }
  136.  
  137. func standardized() -> Self {
  138. var copy = self
  139. copy.standardize()
  140. return copy
  141. }
  142.  
  143. func translatedBy(_ v: PointType) -> Self {
  144. Self(origin: PointType(x: x + v.x, y: y + v.y), size: SizeType(width: width, height: height))
  145. }
  146.  
  147. func intersection(_ r2: Self) -> Self? {
  148. if minX < r2.maxX, maxX > r2.minX, minY < r2.maxY, maxY > r2.minY {
  149. return Self(minX: Swift.max(minX, r2.minX),
  150. minY: Swift.max(minY, r2.minY),
  151. maxX: Swift.min(maxX, r2.maxX),
  152. maxY: Swift.min(maxY, r2.maxY))
  153. } else {
  154. return nil
  155. }
  156. }
  157.  
  158. func inset(by insets: GenericInsets<ValueType>) -> Self {
  159. Self(minX: minX + insets.left,
  160. minY: minY + insets.top,
  161. maxX: maxX - insets.bottom,
  162. maxY: maxY - insets.right)
  163. }
  164.  
  165. static var zero: Self { Self(origin: .zero, size: .zero) }
  166. }
  167.  
  168. extension GenericRect {
  169. init(x: ValueType, y: ValueType, width: ValueType, height: ValueType) {
  170. self.init(origin: PointType(x: x, y: y),
  171. size: SizeType(width: width, height: height))
  172. }
  173.  
  174. init(_ x: ValueType, _ y: ValueType, _ w: ValueType, _ h: ValueType) {
  175. self.init(x: x, y: y, width: w, height: h)
  176. }
  177.  
  178. init(minX: ValueType, minY: ValueType, maxX: ValueType, maxY: ValueType) {
  179. self.init(minX, minY, maxX - minX, maxY - minY)
  180. }
  181.  
  182. init(origin: PointType, bottomRight: PointType) {
  183. self.init(minX: origin.x, minY: origin.y, maxX: bottomRight.x, maxY: bottomRight.y)
  184. }
  185. }
  186.  
  187. protocol Divisible {
  188. static func / (lhs: Self, rhs: Self) -> Self
  189. }
  190.  
  191. extension Float: Divisible {}
  192. extension Int: Divisible {}
  193.  
  194. extension GenericRect where ValueType: Divisible {
  195. var center: PointType {
  196. get { PointType(x: midX, y: midY) }
  197. set { midX = newValue.x; midY = newValue.y }
  198. }
  199.  
  200. var midX: ValueType {
  201. get { x + (width / 2) }
  202. set { x = newValue - width / 2 }
  203. }
  204.  
  205. var midY: ValueType {
  206. get { y + (height / 2) }
  207. set { y = newValue - height / 2 }
  208. }
  209.  
  210. var bottomCenter: PointType { PointType(x: midX, y: maxY) }
  211. }
  212.  
  213. extension GenericRect: Sequence where ValueType: Strideable {
  214. typealias Element = PointType
  215.  
  216. func makeIterator() -> AnyIterator<PointType> {
  217. var at = origin
  218. return AnyIterator {
  219. if at.x == self.width {
  220. at.y += 1
  221. at.x = 0
  222. }
  223. guard at.y < self.height else { return nil }
  224. defer { at.x += 1 }
  225. return at
  226. }
  227. }
  228. }
  229.  
  230. struct GenericInsets<ValueType: GeometricValue>: Equatable {
  231. var top: ValueType
  232. var left: ValueType
  233. var bottom: ValueType
  234. var right: ValueType
  235.  
  236. static var zero: Self { Self(top: 0, left: 0, bottom: 0, right: 0) }
  237. }
  238.  
  239. typealias Point = GenericPoint<Int>
  240. typealias Size = GenericSize<Int>
  241. typealias Rect = GenericRect<Int>
  242. typealias EdgeInsets = GenericInsets<Int>
  243.  
  244. typealias PointF = GenericPoint<Float>
  245. typealias SizeF = GenericSize<Float>
  246. typealias RectF = GenericRect<Float>
  247. typealias EdgeInsetsF = GenericInsets<Float>
  248.  
  249. extension Point {
  250. init(_ point: PointF) {
  251. self.init(Int(point.x.rounded(.down)), Int(point.y.rounded(.down)))
  252. }
  253. }
  254.  
  255. extension PointF {
  256. init(_ point: Point) {
  257. self.init(Float(point.x), Float(point.y))
  258. }
  259. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement