Last active
January 10, 2024 15:26
-
-
Save detomon/864a6b7c51f8bed7a022 to your computer and use it in GitHub Desktop.
Convenient operator overloadings for CGPoint, CGSize and CGRect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
/** | |
* CGAffineTransform | |
* | |
* var a = CGAffineTransformMakeRotation(45.0 * M_PI / 180.0) | |
* var b = CGPointMake(30.0, 43.3) | |
*/ | |
/** | |
* ... | |
* a + b | |
*/ | |
func + (left: CGAffineTransform, right: CGPoint) -> CGAffineTransform { | |
return left.translatedBy(x: right.x, y: right.y) | |
} | |
/** | |
* ... | |
* a += b | |
*/ | |
func += (left: inout CGAffineTransform, right: CGPoint) { | |
left = left + right | |
} | |
/** | |
* ... | |
* a - b | |
*/ | |
func - (left: CGAffineTransform, right: CGPoint) -> CGAffineTransform { | |
return left.translatedBy(x: -right.x, y: -right.y) | |
} | |
/** | |
* ... | |
* a -= b | |
*/ | |
func -= (left: inout CGAffineTransform, right: CGPoint) { | |
left = left - right | |
} | |
/** | |
* ... | |
* a * b | |
*/ | |
func * (left: CGAffineTransform, right: CGPoint) -> CGAffineTransform { | |
return left.scaledBy(x: right.x, y: right.y) | |
} | |
/** | |
* ... | |
* a *= b | |
*/ | |
func *= (left: inout CGAffineTransform, right: CGPoint) { | |
left = left * right | |
} | |
/** | |
* Multiply transformation with CGPoint | |
*/ | |
func * (left: CGAffineTransform, right: CGPoint) -> CGPoint { | |
return CGPoint( | |
x: left.a * right.x + left.b * right.y + left.tx, | |
y: left.c * right.x + left.d * right.y + left.ty | |
) | |
} | |
/** | |
* Multiply transformation with CGSize | |
*/ | |
func * (left: CGAffineTransform, right: CGSize) -> CGSize { | |
return CGSize( | |
width: left.a * right.width + left.b * right.height + left.tx, | |
height: left.c * right.width + left.d * right.height + left.ty | |
) | |
} | |
/** | |
* Multiply transformation with CGRect | |
* Only scale and translation operations are meaningful | |
*/ | |
func * (left: CGAffineTransform, right: CGRect) -> CGRect { | |
var point1 = CGPoint(x: right.origin.x, y: right.origin.y) | |
var point2 = CGPoint(x: right.maxX, y: right.maxY) | |
point1 = left * point1 | |
point2 = left * point2 | |
return CGRect(x: point1.x, y: point1.y, width: point2.x - point1.x, height: point2.y - point1.y) | |
} | |
/** | |
* Rotation operator | |
*/ | |
infix operator *^: MultiplicationPrecedence | |
/** | |
* Rotate transformation | |
* | |
* var transform = CGAffineTransformMakeTranslation(100, 120) | |
* transform = transform *^ (45.0 * M_PI / 180.0) | |
*/ | |
func *^ (left: CGAffineTransform, right: CGFloat) -> CGAffineTransform { | |
return left.rotated(by: right) | |
} | |
/** | |
* Invert transformation | |
* | |
* var transform = CGAffineTransformMakeRotation(127.0 * M_PI / 180.0) | |
* transform = ~transform | |
*/ | |
prefix func ~ (left: CGAffineTransform) -> CGAffineTransform { | |
return left.inverted() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
/** | |
* CGPoint | |
* | |
* var a = CGPointMake(13.5, -34.2) | |
* var b = CGPointMake(8.9, 22.4) | |
* ... | |
*/ | |
/** | |
* ... | |
* a + b | |
*/ | |
func + (left: CGPoint, right: CGPoint) -> CGPoint { | |
return CGPoint(x: left.x + right.x, y: left.y + right.y) | |
} | |
/** | |
* ... | |
* a += b | |
*/ | |
func += (left: inout CGPoint, right: CGPoint) { | |
left = left + right | |
} | |
/** | |
* ... | |
* a -= b | |
*/ | |
func - (left: CGPoint, right: CGPoint) -> CGPoint { | |
return CGPoint(x: left.x - right.x, y: left.y - right.y) | |
} | |
/** | |
* ... | |
* a -= b | |
*/ | |
func -= (left: inout CGPoint, right: CGPoint) { | |
left = left - right | |
} | |
/** | |
* ... | |
* a * b | |
*/ | |
func * (left: CGPoint, right: CGPoint) -> CGPoint { | |
return CGPoint(x: left.x * right.x, y: left.y * right.y) | |
} | |
/** | |
* ... | |
* a *= b | |
*/ | |
func *= (left: inout CGPoint, right: CGPoint) { | |
left = left * right | |
} | |
/** | |
* ... | |
* a / b | |
*/ | |
func / (left: CGPoint, right: CGPoint) -> CGPoint { | |
return CGPoint(x: left.x / right.x, y: left.y / right.y) | |
} | |
/** | |
* ... | |
* a /= b | |
*/ | |
func /= (left: inout CGPoint, right: CGPoint) { | |
left = left / right | |
} | |
/** | |
* ... | |
* a * 10.4 | |
*/ | |
func * (left: CGPoint, right: CGFloat) -> CGPoint { | |
return CGPoint(x: left.x * right, y: left.y * right) | |
} | |
/** | |
* ... | |
* a *= 10.4 | |
*/ | |
func *= (left: inout CGPoint, right: CGFloat) { | |
left = left * right | |
} | |
/** | |
* ... | |
* a / 10.4 | |
*/ | |
func / (left: CGPoint, right: CGFloat) -> CGPoint { | |
return CGPoint(x: left.x / right, y: left.y / right) | |
} | |
/** | |
* ... | |
* a /= 10.4 | |
*/ | |
func /= (left: inout CGPoint, right: CGFloat) { | |
left = left / right | |
} | |
/** | |
* var c = CGSizeMake(20.4, 75.8) | |
* ... | |
*/ | |
/** | |
* ... | |
* a + c | |
*/ | |
func + (left: CGPoint, right: CGSize) -> CGPoint { | |
return CGPoint(x: left.x + right.width, y: left.y + right.height) | |
} | |
/** | |
* ... | |
* a += c | |
*/ | |
func += (left: inout CGPoint, right: CGSize) { | |
left = left + right | |
} | |
/** | |
* ... | |
* a - c | |
*/ | |
func - (left: CGPoint, right: CGSize) -> CGPoint { | |
return CGPoint(x: left.x - right.width, y: left.y - right.height) | |
} | |
/** | |
* ... | |
* a -= c | |
*/ | |
func -= (left: inout CGPoint, right: CGSize) { | |
left = left - right | |
} | |
/** | |
* ... | |
* a * c | |
*/ | |
func * (left: CGPoint, right: CGSize) -> CGPoint { | |
return CGPoint(x: left.x * right.width, y: left.y * right.height) | |
} | |
/** | |
* ... | |
* a *= c | |
*/ | |
func *= (left: inout CGPoint, right: CGSize) { | |
left = left * right | |
} | |
/** | |
* ... | |
* a / c | |
*/ | |
func / (left: CGPoint, right: CGSize) -> CGPoint { | |
return CGPoint(x: left.x / right.width, y: left.y / right.height) | |
} | |
/** | |
* ... | |
* a /= c | |
*/ | |
func /= (left: inout CGPoint, right: CGSize) { | |
left = left / right | |
} | |
/** | |
* ... | |
* -a | |
*/ | |
prefix func - (left: CGPoint) -> CGPoint { | |
return CGPoint(x: -left.x, y: -left.y) | |
} | |
extension CGPoint { | |
/** | |
* Get point by rounding to nearest integer value | |
*/ | |
var integerPoint: CGPoint { | |
return CGPoint( | |
x: CGFloat(Int(self.x >= 0.0 ? self.x + 0.5 : self.x - 0.5)), | |
y: CGFloat(Int(self.y >= 0.0 ? self.y + 0.5 : self.y - 0.5)) | |
) | |
} | |
} | |
/** | |
* Get minimum x and y values of multiple points | |
*/ | |
func min(a: CGPoint, b: CGPoint, rest: CGPoint...) -> CGPoint { | |
var p = CGPoint(x: min(a.x, b.x), y: min(a.y, b.y)) | |
for point in rest { | |
p.x = min(p.x, point.x) | |
p.y = min(p.y, point.y) | |
} | |
return p | |
} | |
/** | |
* Get maximum x and y values of multiple points | |
*/ | |
func max(a: CGPoint, b: CGPoint, rest: CGPoint...) -> CGPoint { | |
var p = CGPoint(x: max(a.x, b.x), y: max(a.y, b.y)) | |
for point in rest { | |
p.x = max(p.x, point.x) | |
p.y = max(p.y, point.y) | |
} | |
return p | |
} | |
/** | |
* CGSize | |
*/ | |
/** | |
* var a = CGSizeMake(8.9, 14.5) | |
* var b = CGSizeMake(20.4, 75.8) | |
* ... | |
*/ | |
/** | |
* ... | |
* a + b | |
*/ | |
func + (left: CGSize, right: CGSize) -> CGSize { | |
return CGSize(width: left.width + right.width, height: left.height + right.height) | |
} | |
/** | |
* ... | |
* a += b | |
*/ | |
func += (left: inout CGSize, right: CGSize) { | |
left = left + right | |
} | |
/** | |
* ... | |
* a - b | |
*/ | |
func - (left: CGSize, right: CGSize) -> CGSize { | |
return CGSize(width: left.width - right.width, height: left.height - right.height) | |
} | |
/** | |
* ... | |
* a -= b | |
*/ | |
func -= (left: inout CGSize, right: CGSize) { | |
left = left - right | |
} | |
/** | |
* ... | |
* a * b | |
*/ | |
func * (left: CGSize, right: CGSize) -> CGSize { | |
return CGSize(width: left.width * right.width, height: left.height * right.height) | |
} | |
/** | |
* ... | |
* a *= b | |
*/ | |
func *= (left: inout CGSize, right: CGSize) { | |
left = left * right | |
} | |
/** | |
* ... | |
* a / b | |
*/ | |
func / (left: CGSize, right: CGSize) -> CGSize { | |
return CGSize(width: left.width / right.width, height: left.height / right.height) | |
} | |
/** | |
* ... | |
* a /= b | |
*/ | |
func /= (left: inout CGSize, right: CGSize) { | |
left = left / right | |
} | |
/** | |
* var c = CGPointMake(-3.5, -17.6) | |
* ... | |
*/ | |
/** | |
* ... | |
* a + c | |
*/ | |
func + (left: CGSize, right: CGPoint) -> CGSize { | |
return CGSize(width: left.width + right.x, height: left.height + right.y) | |
} | |
/** | |
* ... | |
* a += c | |
*/ | |
func += (left: inout CGSize, right: CGPoint) { | |
left = left + right | |
} | |
/** | |
* ... | |
* a - c | |
*/ | |
func - (left: CGSize, right: CGPoint) -> CGSize { | |
return CGSize(width: left.width - right.x, height: left.height - right.y) | |
} | |
/** | |
* ... | |
* a -= c | |
*/ | |
func -= (left: inout CGSize, right: CGPoint) { | |
left = left - right | |
} | |
/** | |
* ... | |
* a * c | |
*/ | |
func * (left: CGSize, right: CGPoint) -> CGSize { | |
return CGSize(width: left.width * right.x, height: left.height * right.y) | |
} | |
/** | |
* ... | |
* a *= c | |
*/ | |
func *= (left: inout CGSize, right: CGPoint) { | |
left = left * right | |
} | |
/** | |
* ... | |
* a / c | |
*/ | |
func / (left: CGSize, right: CGPoint) -> CGSize { | |
return CGSize(width: left.width / right.x, height: left.height / right.y) | |
} | |
/** | |
* ... | |
* a /= c | |
*/ | |
func /= (left: inout CGSize, right: CGPoint) { | |
left = left / right | |
} | |
/** | |
* ... | |
* a * 4.6 | |
*/ | |
func * (left: CGSize, right: CGFloat) -> CGSize { | |
return CGSize(width: left.width * right, height: left.height * right) | |
} | |
/** | |
* ... | |
* a *= 4.6 | |
*/ | |
func *= (left: inout CGSize, right: CGFloat) { | |
left = left * right | |
} | |
/** | |
* CGRect | |
* | |
* var a = CGRectMake(30.4, 58.6, 20.3, 78.3) | |
* var b = CGPointMake(-16.7, 40.5) | |
* ... | |
*/ | |
/** | |
* ... | |
* a + b | |
*/ | |
func + (left: CGRect, right: CGPoint) -> CGRect { | |
return CGRect(x: left.origin.x + right.x, y: left.origin.y + right.y, width: left.size.width, height: left.size.height) | |
} | |
/** | |
* ... | |
* a += b | |
*/ | |
func += (left: inout CGRect, right: CGPoint) { | |
left = left + right | |
} | |
/** | |
* ... | |
* a - b | |
*/ | |
func - (left: CGRect, right: CGPoint) -> CGRect { | |
return CGRect(x: left.origin.x - right.x, y: left.origin.y - right.y, width: left.size.width, height: left.size.height) | |
} | |
/** | |
* ... | |
* a -= b | |
*/ | |
func -= (left: inout CGRect, right: CGPoint) { | |
left = left - right | |
} | |
/** | |
* ... | |
* a * 2.5 | |
*/ | |
func * (left: CGRect, right: CGFloat) -> CGRect { | |
return CGRect(x: left.origin.x * right, y: left.origin.y * right, width: left.size.width * right, height: left.size.height * right) | |
} | |
/** | |
* ... | |
* a *= 2.5 | |
*/ | |
func *= (left: inout CGRect, right: CGFloat) { | |
left = left * right | |
} | |
/** | |
* ... | |
* a / 4.0 | |
*/ | |
func / (left: CGRect, right: CGFloat) -> CGRect { | |
return CGRect(x: left.origin.x / right, y: left.origin.y / right, width: left.size.width / right, height: left.size.height / right) | |
} | |
/** | |
* ... | |
* a /= 4.0 | |
*/ | |
func /= (left: inout CGRect, right: CGFloat) { | |
left = left / right | |
} | |
extension CGRect { | |
/** | |
* Extend CGRect by CGPoint | |
*/ | |
mutating func union(withPoint: CGPoint) { | |
if withPoint.x < self.origin.x { self.size.width += self.origin.x - withPoint.x; self.origin.x = withPoint.x } | |
if withPoint.y < self.origin.y { self.size.height += self.origin.y - withPoint.y; self.origin.y = withPoint.y } | |
if withPoint.x > self.origin.x + self.size.width { self.size.width = withPoint.x - self.origin.x } | |
if withPoint.y > self.origin.y + self.size.height { self.size.height = withPoint.y - self.origin.y; } | |
} | |
/** | |
* Get end point of CGRect | |
*/ | |
func maxPoint() -> CGPoint { | |
return CGPoint(x: self.origin.x + self.size.width, y: self.origin.y + self.size.height) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@Mazyod Fixed, thanks!