Created
August 14, 2014 18:48
-
-
Save maxbucknell/4c60e584b81cb9085722 to your computer and use it in GitHub Desktop.
A few extensions for vector spaces
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 UIKit | |
/** | |
* A vector space (!) | |
*/ | |
protocol VectorSpace { | |
var identity: Self { get } | |
var magnitude: CGFloat { get } | |
func multiplyByScalar(scalar: CGFloat) -> Self | |
func add(right: Self) -> Self | |
} | |
/** | |
* Scalar multiplication (Commutative) | |
*/ | |
func *<Vector: VectorSpace>(left: Vector, right: CGFloat) -> Vector { | |
return left.multiplyByScalar(right) | |
} | |
func *<Vector: VectorSpace>(left: CGFloat, right: Vector) -> Vector { | |
return right * left | |
} | |
func *=<Vector: VectorSpace>(inout left: Vector, right: CGFloat) -> Void{ | |
left = left * right | |
} | |
/** | |
* Scalar division | |
*/ | |
func /<Vector: VectorSpace>(left: Vector, right: CGFloat) -> Vector { | |
return left * pow(right, -1) | |
} | |
func /=<Vector: VectorSpace>(inout left: Vector, right: CGFloat) -> Void { | |
left = left / right | |
} | |
/** | |
* Unary addition (no-op) | |
*/ | |
prefix func +<Vector: VectorSpace>(subject: Vector) -> Vector { | |
return subject | |
} | |
/** | |
* Binary addition | |
*/ | |
func +<Vector: VectorSpace>(left: Vector, right: Vector) -> Vector { | |
return left.add(right) | |
} | |
func +=<Vector: VectorSpace>(inout left: Vector, right: Vector) -> Void{ | |
left = left + right | |
} | |
/** | |
* Unary subtraction | |
*/ | |
prefix func -<Vector: VectorSpace>(subject: Vector) -> Vector { | |
return subject * -1 | |
} | |
/** | |
* Binary subtraction | |
*/ | |
func -<Vector: VectorSpace>(left: Vector, right: Vector) -> Vector { | |
return left.add(-right) | |
} | |
func -=<Vector: VectorSpace>(inout left: Vector, right: Vector) -> Void{ | |
left = left - right | |
} | |
/** | |
* Make CGPoint a VectorSpace | |
*/ | |
extension CGPoint: VectorSpace { | |
var identity: CGPoint { | |
get { | |
return CGPointZero | |
} | |
} | |
var magnitude: CGFloat { | |
get { | |
return sqrt(self.x * self.x + self.y * self.y) | |
} | |
} | |
func multiplyByScalar(scalar: CGFloat) -> CGPoint { | |
return CGPointMake(self.x * scalar, self.y * scalar) | |
} | |
func add(right: CGPoint) -> CGPoint { | |
return CGPointMake(self.x + right.x, self.y + right.y) | |
} | |
} | |
/** | |
* Make CGVector a Vector Space | |
*/ | |
extension CGVector: VectorSpace { | |
var identity: CGVector { | |
get { | |
return CGVectorMake(0, 0) | |
} | |
} | |
var magnitude: CGFloat { | |
get { | |
return sqrt(self.dx * self.dx + self.dy * self.dy) | |
} | |
} | |
func multiplyByScalar(scalar: CGFloat) -> CGVector { | |
return CGVectorMake(self.dx * scalar, self.dy * scalar) | |
} | |
func add(right: CGVector) -> CGVector { | |
return CGVectorMake(self.dx + right.dx, self.dy + right.dy) | |
} | |
} | |
/** | |
* Make CGSize a Vector Space | |
*/ | |
extension CGSize: VectorSpace { | |
var identity: CGSize { | |
get { | |
return CGSizeMake(0, 0) | |
} | |
} | |
var magnitude: CGFloat { | |
get { | |
return sqrt(self.width * self.width + self.height * self.height) | |
} | |
} | |
func multiplyByScalar(scalar: CGFloat) -> CGSize { | |
return CGSizeMake(self.width * scalar, self.height * scalar) | |
} | |
func add(right: CGSize) -> CGSize { | |
return CGSizeMake(self.width + right.width, self.height + right.height) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment