Move vector stuff to its own Swift file and finish 'em up!

This commit is contained in:
Eryn Wells 2015-10-29 10:56:31 -07:00
parent e7e53ba73c
commit d1bd19a356
3 changed files with 256 additions and 115 deletions

View file

@ -11,6 +11,7 @@
C005E0051BE1CBA800F1BD3C /* Math.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C005DFFA1BE1CBA700F1BD3C /* Math.framework */; };
C005E00A1BE1CBA800F1BD3C /* MathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C005E0091BE1CBA800F1BD3C /* MathTests.swift */; };
C005E0391BE1CC7A00F1BD3C /* Matrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = C005E0381BE1CC7A00F1BD3C /* Matrix.swift */; };
C04449C11BE26A0700ABF046 /* Vector.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04449C01BE26A0700ABF046 /* Vector.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -31,6 +32,7 @@
C005E0091BE1CBA800F1BD3C /* MathTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MathTests.swift; sourceTree = "<group>"; };
C005E00B1BE1CBA800F1BD3C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C005E0381BE1CC7A00F1BD3C /* Matrix.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Matrix.swift; sourceTree = "<group>"; };
C04449C01BE26A0700ABF046 /* Vector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Vector.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -75,6 +77,7 @@
children = (
C005DFFD1BE1CBA700F1BD3C /* Math.h */,
C005E0381BE1CC7A00F1BD3C /* Matrix.swift */,
C04449C01BE26A0700ABF046 /* Vector.swift */,
C005DFFF1BE1CBA700F1BD3C /* Info.plist */,
);
path = Math;
@ -197,6 +200,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C04449C11BE26A0700ABF046 /* Vector.swift in Sources */,
C005E0391BE1CC7A00F1BD3C /* Matrix.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View file

@ -20,21 +20,6 @@ protocol Matrix {
subscript(row: Int, col: Int) -> ElementType { get set }
}
/** A vector. */
protocol Vector {
init()
/** Number of elements in the vector. */
var count: Int { get }
/** Element access by index. */
subscript(idx: Int) -> Float { get set }
/** Length of the vector. */
var length2: Float { get }
/** Length-squared of the vector. */
var length: Float { get }
}
// MARK: - Matrices
public struct Matrix4<T: FloatingPointType>: Matrix {
@ -90,107 +75,7 @@ struct Matrix3 {
// MARK: Vectors
public struct Vector3: Vector {
private var data: [Float]
init() {
self.init(x: 0.0, y: 0.0, z: 0.0)
}
init(x: Float, y: Float, z: Float) {
data = [x, y, z]
}
var length: Float {
return sqrtf(length2)
}
var length2: Float {
return data.reduce(0.0) { $0 + $1 * $1 }
}
// MARK: Sequence-ish
var count: Int {
return 3
}
public subscript(idx: Int) -> Float {
get {
return data[idx]
}
set(value) {
data[idx] = value
}
}
// MARK: Element access
var x: Float {
return data[0]
}
var y: Float {
return data[1]
}
var z: Float {
return data[2]
}
}
public struct Vector4: Vector {
private var data: [Float]
init() {
self.init(x: 0.0, y: 0.0, z: 0.0)
}
init(x: Float, y: Float, z: Float, w: Float = 1.0) {
data = [x, y, z, w]
}
var length: Float {
return sqrtf(length2)
}
var length2: Float {
return data.reduce(0.0) { $0 + $1 * $1 }
}
// MARK: SequenceType-ish
var count: Int {
return data.count
}
public subscript(idx: Int) -> Float {
get {
return data[idx]
}
set(value) {
data[idx] = value
}
}
// MARK: Element access
var x: Float {
return data[0]
}
var y: Float {
return data[1]
}
var z: Float {
return data[2]
}
var w: Float {
return data[3]
}
}
// MARK: - Matrix-Scalar Multiplication

252
Math/Math/Vector.swift Normal file
View file

@ -0,0 +1,252 @@
//
// Vector.swift
// Math
//
// Created by Eryn Wells on 10/29/15.
// Copyright © 2015 Eryn Wells. All rights reserved.
//
import Foundation
public typealias Float = Swift.Float
/** A vector. */
public protocol Vector {
init()
/** Number of elements in the vector. */
var count: Int { get }
/** Element access by index. */
subscript(idx: Int) -> Float { get set }
/** Length of the vector. */
var length2: Float { get }
/** Length-squared of the vector. */
var length: Float { get }
/** A normalized copy of the vector. */
var normalized: Self { get }
/** The dot product of this vector with another. */
func dot(lhs: Self) -> Float
}
extension Vector {
public var length: Float {
return sqrtf(length2)
}
public var length2: Float {
var l2: Float = 0.0
for i in 0..<self.count {
l2 += self[i] * self[i]
}
return l2
}
public var normalized: Self {
return self / length
}
}
/** A vector with three components: X, Y, and Z. */
public struct Vector3: Vector {
private var data: [Float]
public init() {
self.init(x: 0.0, y: 0.0, z: 0.0)
}
public init(v: Vector4) {
self.init(x: v.x, y: v.y, z: v.z)
}
public init(x: Float, y: Float, z: Float) {
data = [x, y, z]
}
// MARK: CollectionType-ish
public var count: Int {
return data.count
}
public subscript(idx: Int) -> Float {
get {
return data[idx]
}
set(value) {
data[idx] = value
}
}
// MARK: Element access
public var x: Float {
get {
return data[0]
}
set(value) {
data[0] = value
}
}
public var y: Float {
get {
return data[1]
}
set(value) {
data[1] = value
}
}
public var z: Float {
get {
return data[2]
}
set(value) {
data[2] = value
}
}
// MARK: Operators
public func cross(rhs: Vector3) -> Vector3 {
return Vector3(x: data[1] * rhs.data[2] - data[2] * rhs.data[1],
y: data[2] * rhs.data[0] - data[0] * rhs.data[2],
z: data[0] * rhs.data[1] - data[1] * rhs.data[0])
}
}
//------------------------------------------------------------------------------
public struct Vector4: Vector {
private var data: [Float]
public init() {
self.init(x: 0.0, y: 0.0, z: 0.0)
}
public init(v: Vector3, w: Float = 1.0) {
self.init(x: v.x, y: v.y, z: v.z, w: w)
}
public init(x: Float, y: Float, z: Float, w: Float = 1.0) {
data = [x, y, z, w]
}
// MARK: SequenceType-ish
public var count: Int {
return data.count
}
public subscript(idx: Int) -> Float {
get {
return data[idx]
}
set(value) {
data[idx] = value
}
}
// MARK: Element access
public var x: Float {
return data[0]
}
public var y: Float {
return data[1]
}
public var z: Float {
return data[2]
}
public var w: Float {
return data[3]
}
}
// MARK: - Operators
extension Vector {
public func dot(rhs: Self) -> Float {
var sum: Float = 0.0
for i in 0..<self.count {
sum += self[i] * rhs[i]
}
return sum
}
}
public prefix func -<T: Vector>(v: T) -> T {
var out = v
for i in 0..<out.count {
out[i] -= -out[i]
}
return out
}
public func +=<T: Vector>(inout rhs: T, lhs: T) {
for i in 0..<rhs.count {
rhs[i] += lhs[i]
}
}
public func +<T: Vector>(rhs: T, lhs: T) -> T {
var out = rhs
out += lhs
return out
}
public func -=<T: Vector>(inout rhs: T, lhs: T) {
for i in 0..<rhs.count {
rhs[i] -= lhs[i]
}
}
public func -<T: Vector>(rhs: T, lhs: T) -> T {
var out = rhs
out -= lhs
return out
}
public func *=<T: Vector>(inout rhs: T, lhs: Float) {
for i in 0..<rhs.count {
rhs[i] *= lhs
}
}
public func *<T: Vector>(lhs: Float, rhs: T) -> T {
var out = rhs
out *= lhs
return out
}
public func *<T: Vector>(lhs: T, rhs: Float) -> T {
return rhs * lhs
}
public func /=<T: Vector>(inout rhs: T, lhs: Float) {
rhs *= (1.0 / lhs)
}
public func /<T: Vector>(lhs: T, rhs: Float) -> T {
return lhs * (1.0 / rhs)
}
infix operator { associativity left precedence 150 }
public func <T: Vector>(rhs: T, lhs: T) -> Float {
return rhs.dot(lhs)
}
infix operator ×= { associativity left precedence 150 }
public func ×=(inout rhs: Vector3, lhs: Vector3) {
rhs = rhs.cross(lhs)
}
infix operator × { associativity left precedence 150 }
public func ×(rhs: Vector3, lhs: Vector3) -> Vector3 {
return rhs.cross(lhs)
}