Travis Swift 4.2 Swift 5.0 License Twitter

目的

VectorMath 是一个用于 Mac 和 iOS 的 Swift 库,它实现了常用的 2D 和 3D 向量和矩阵函数,非常适用于游戏或基于向量的图形。

VectorMath 利用了 Swift 语言的特性,例如函数和运算符重载以及结构体方法,以提供比大多数基于 C、C++ 或 Cocoa 的图形 API 更优雅的接口。

VectorMath 还为 GLKit 向量数学类型和函数提供了方便的替代方案,这些类型和函数由于依赖于联合类型,目前在 Swift 中尚不可用。

VectorMath 是一个完全独立的库,仅依赖于 Foundation 框架。然而,它为 SceneKit 和 Quartz (CoreGraphics/CoreAnimation) 提供了可选的兼容性扩展,以便与 UIKit、AppKit、SpriteKit 和 SceneKit 互操作。

VectorMath 的设计目标是高效,但尚未经过大量优化,并且尚未利用使用 Accelerate 框架的特定于架构的硬件加速。

支持的操作系统和 SDK 版本

注意: “支持” 表示该库已在此版本上进行过测试。“兼容” 表示该库应在此操作系统版本上工作(即,它不依赖于任何不可用的 SDK 功能),但不再针对兼容性进行测试,并且可能需要调整或错误修复才能正确运行。

安装

要在应用程序中使用 VectorMath 函数,请将 VectorMath.swift 文件(不需要 demo/test 文件和资源)拖到您的项目中。 您可能还希望包含 VectorMath+SceneKit.swift 和/或 VectorMath+Quartz.swift 兼容性扩展。

类型

VectorMath 声明了以下类型

Scalar

这是一个类型别名,用于 VectorMath 库中的标量浮点值。 默认情况下设置为 Float,但您可以将其更改为 Double 或 CGFloat,以提高特定应用程序的性能。

Vector2
Vector3
Vector4

这些分别代表 2D、3D 和 4D 向量。

Matrix3
Matrix4

这些分别代表齐次 3x3 和 4x4 变换矩阵。

Quaternion

这表示 3D 空间中的旋转。 它具有与 Vector4D 相同的结构,但由于不同的用例和方法,被定义为不同的类型。

所有 VectorMath 类型都符合 Equatable 和 Hashable 协议,因此可以存储在 Swift 字典中。

常量

VectorMath 为了您的方便声明了许多命名空间的常量。 它们如下所示

Scalar.pi
Scalar.halfPi
Scalar.quarterPi
Scalar.twoPi

这些应该是自解释的。

Scalar.degreesPerRadian
Scalar.radiansPerDegree

度数和弧度之间的转换因子。 例如,要将 40 度转换为弧度,您可以说 let r = 40 * .degreesPerRadian,或者要将 Pi/2 弧度转换为度数,请说 let d = .halfPi * .radiansPerDegree

Scalar.epsilon = 0.0001

这是一个浮点误差值,由近似相等运算符使用。 如果它对于您的需求来说不够(或过度)精确,您可以更改它。

Vector2.zero
Vector3.zero
Vector4.zero
Quaternion.Zero

这些是零向量常量,可用作向量的默认值

Vector2.x
Vector2.y
Vector3.x
Vector3.y
Vector3.z
Vector4.x
Vector4.y
Vector4.z
Vector4.w

这些是沿各种轴的单位向量。 例如,Vector3.z 的值为 Vector3(0, 0, 1)

Matrix3.identity
Matrix4.identity
Quaternion.identity

这些是单位矩阵,其属性是将其与另一个矩阵或向量相乘无效。

方法

下面给出了 VectorMath 属性和方法的完整列表。 这些大多是自解释的。 如果您找不到您正在寻找的方法(例如,使用四元数旋转向量的方法),则它可能作为运算符实现(请参阅下面的“运算符”)。

Vector2
    init(x: Scalar, y: Scalar)
    init(_: Scalar, _: Scalar)
    init(_: [Scalar])
    lengthSquared: Scalar
    length: Scalar
    inverse: Vector2
    toArray() -> [Scalar]
    dot(Vector2) -> Scalar
    cross(Vector2) -> Scalar
    normalized() -> Vector2
    rotated(by: Scalar) -> Vector2
    rotated(by: Scalar, around: Vector2) -> Vector2
    angle(with: Vector2) -> Scalar
    interpolated(with: Vector2, by: Scalar) -> Vector2

Vector3
    init(x: Scalar, y: Scalar, z: Scalar)
    init(_: Scalar, _: Scalar, _: Scalar)
    init(_: [Scalar])
    lengthSquared: Scalar
    length: Scalar
    inverse: Vector3
    xy: Vector2
    xz: Vector2
    yz: Vector2
    toArray() -> [Scalar]
    dot(Vector3) -> Scalar
    cross(Vector3) -> Vector3
    normalized() -> Vector3
    interpolated(with: Vector3, by: Scalar) -> Vector3

Vector4
    init(x: Scalar, y: Scalar, z: Scalar, w: Scalar)
    init(_: Scalar, _: Scalar, _: Scalar, _: Scalar)
    init(_: Vector3, w: Scalar)
    init(_: [Scalar])
    lengthSquared: Scalar
    length: Scalar
    inverse: Vector4
    xyz: Vector3
    xy: Vector2
    xz: Vector2
    yz: Vector2
    toArray() -> [Scalar]
    toVector3() -> Vector3
    dot(Vector4) -> Scalar
    normalized() -> Vector4
    interpolated(with: Vector4, by: Scalar) -> Vector4

Matrix3
    init(m11: Scalar, m12: Scalar, ... m33: Scalar)
    init(_: Scalar, _: Scalar, ... _: Scalar)
    init(scale: Vector2)
    init(translation: Vector2)
    init(rotation: Scalar)
    init(_: [Scalar])
    adjugate: Matrix3
    determinant: Scalar
    transpose: Matrix3
    inverse: Matrix3
    toArray() -> [Scalar]
    interpolated(with: Matrix3, by: Scalar) -> Matrix3

Matrix4
    init(m11: Scalar, m12: Scalar, ... m33: Scalar)
    init(_: Scalar, _: Scalar, ... _: Scalar)
    init(scale: Vector3)
    init(translation: Vector3)
    init(rotation: Vector4)
    init(quaternion: Quaternion)
    init(fovx: Scalar, fovy: Scalar, near: Scalar, far: Scalar)
    init(fovx: Scalar, aspect: Scalar, near: Scalar, far: Scalar)
    init(fovy: Scalar, aspect: Scalar, near: Scalar, far: Scalar)
    init(top: Scalar, right: Scalar, bottom: Scalar, left: Scalar, near: Scalar, far: Scalar)
    init(_: [Scalar])
    adjugate: Matrix4
    determinant: Scalar
    transpose: Matrix4
    inverse: Matrix4
    toArray() -> [Scalar]
    interpolated(with: Matrix3, by: Scalar) -> Matrix3

Quaternion
    init(x: Scalar, y: Scalar, z: Scalar, w: Scalar)
    init(_: Scalar, _: Scalar, _: Scalar, _: Scalar)
    init(axisAngle: Vector4)
    init(pitch: Scalar, yaw: Scalar, roll: Scalar)
    init(rotationMatrix m: Matrix4)
    init(_: [Scalar])
    lengthSquared: Scalar
    length: Scalar
    inverse: Quaternion
    xyz: Vector3
    pitch: Scalar
    yaw: Scalar
    roll: Scalar
    toAxisAngle() -> Vector4
    toPitchYawRoll() -> (pitch: Scalar, yaw: Scalar, roll: Scalar)
    toArray() -> [Scalar]
    dot(Quaternion) -> Scalar
    normalized() -> Quaternion
    interpolated(with: Quaternion, by: Scalar) -> Quaternion

运算符

VectorMath 大量使用了运算符重载,但我尽量没有过度使用自定义运算符。 唯一定义的非标准运算符是 ~=,意思是“近似相等”,这对于比较 Scalar、Vector 或 Matrix 值的相等性非常有用,因为由于浮点精度问题,它们很少完全相同。

为大多数包含的类型实现了 *、/、+、- 和 == 运算符。 * 特别适用于矩阵和向量变换。 例如,要将矩阵变换 “m” 应用于向量 “v”,您可以编写 m * v。 * 也可以与标量值结合使用来缩放向量。

向量和矩阵支持一元负号用于求反/取反。

点积、叉积和归一化在运算符形式中不可用,但作为各种类型的方法提供。

致谢

VectorMath 中使用的许多算法都从 C 语言的 Kazmath 向量数学库 (https://github.com/Kazade/kazmath) 移植或改编而来,或者源自优秀的 Matrix and Quaternion FAQ (http://www.j3d.org/matrix_faq/matrfaq_latest.html)。

此外,以下人员为该项目做出了直接贡献

(贡献者完整列表)