simd框架关于向量和矩阵使用
simd框架是 Apple 提供的一组高效的数学库
1 向量类型,基本格式:simd_floatN,N 表示维度。
- 基本格式:simd_floatN,N 表示维度
- simd_float2:二维向量 (x, y)
- simd_float3:三维向量 (x, y, z)
- simd_float4:四维向量 (x, y, z, w)
向量在 iOS 的 SceneKit 和 ARKit 中是操作 3D 空间对象的核心工具。向量常用于描述位置、方向、速度、力等。理解并使用向量,可以帮助你更好地进行空间计算和动画
定义:向量是一种表示方向和大小的数学实体
3D 空间中的向量通常用三维坐标表示 ,如 (x, y, z)。
在 iOS 中,simd_float3 是常用的向量类型,或者使用 SceneKit 的 SCNVector3。
swift
let vecxy = simd_float2(x: 0.1, y: 0.2)
let vecxyz = simd_float3(x: 0.1, y: 0.2, z: 0.3)
let vecxyzw = simd_float4(x: 0.1, y: 0.1, z: 0.1, w: 0.1)
/*向量加法*/
let v1 = SCNVector3(x: 1.0, y: 2.0, z: 3.0)
let v2 = simd_float3(x: 2.0, y: 2.0, z: 5.0)
let v4 = simd_float3(x: v1.x + v2.x, y: v1.y + v2.y, z: v1.z + v2.z)
/*向量减法*/
let ve1 = SCNVector3(1.0, 1.0, 1.0)
let ve2 = simd_float3(x: 2.0, y: 2.0, z: 2.0)
let ve3 = simd_float3(x: ve2.x - ve1.x, y: ve2.y - ve1.y, z: ve2.z - ve1.z)
/*向量乘法*/
let scaler:Float = 2.0
let ve_vec1 = simd_float3(x: 1.1, y: 2.1, z: 3.1)
let scaler_vector = SCNVector3(x: ve_vec1.x * scaler, y: ve_vec1.y * scaler, z: ve_vec1.z * scaler)
/*向量长度 模*/
let vector1_mode = sqrt(vector1.x * vector1.x + vector1.y * vector1.y + vector1.z * vector1.z)
/*单位向量 长度为1表示方向*/
let normal_vector1 = SCNVector3(x: vector1.x / vector1_mode, y: vector1.y / vector1_mode, z: vector1.z / vector1_mode)
/*
点乘 用于判断两个向量关系,夹角是否垂直,平行等
公式:dot = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z
*/
let v11 = simd_float3(x: 1.0, y: 2.0, z: 3.0)
let v12 = simd_float3(x: 2.0, y: 3.0, z: 4.0)
let docProduct = simd_dot(v11, v12)
/*
插乘 返回垂直于两个向量的向量
*/
let crossProduct = simd_cross(v11, v12)
/*
向量在ios开发者常见应用
*/
/*计算两个点之间的方向向量*/
let startVector1 = SCNVector3(x: 1.0, y: 1.2, z: 1.3)
let endVector1 = SCNVector3(x: 1.2, y: 3.2, z: 4.1)
let direction = SCNVector3(x: endVector1.x - startVector1.x, y: endVector1.y - startVector1.y, z: endVector1.z - startVector1.z)
/*碰撞检测,判断物体之间距离小于某个值*/
let vectoryA = simd_float3(x: 1.2, y: 3.5, z: 5.2)
let vectoryB = simd_float3(x: 4, y: 5, z: 6)
let distance = sqrt(pow(vectoryA.x - vectoryB.x, 2) + pow(vectoryA.y - vectoryB.y, 2) + pow(vectoryA.z - vectoryA.z, 2))
/*
将物体的朝向调整为指定某个目标
*/
let currentPosition = simd_float3(x: 4.2, y: 1.5, z: 5.3)
let targetPosition = simd_float3(x: 2.1, y: 2.4, z: 3.1)
let direction1 = simd_normalize(targetPosition - currentPosition)
var testNode:SCNNode?
//将物体的朝向调整为指定某个目标,targetPosition 这个目标
testNode?.simdLook(at: direction1)
// SceneKit 的 SCNVector3 与 simd 的 simd_float3 是兼容的
let vec111:SCNVector3 = testNode?.position ?? SCNVector3(x: 0, y: 0, z: 0)
let simdVectory1:simd_float3 = simd_float3(vec111)
let scenVector = SCNVector3(simdVectory1)
**支持的类型:**
- float:simd_floatN
- double:simd_doubleN
- int:simd_intN
2 矩阵类型
基本格式:simd_floatNxM,N 是行数,M 是列数。
- simd_float2x2:2x2 矩阵
- simd_float3x3:3x3 矩阵
- simd_float4x4:4x4 矩阵
swift
let matrix3x3 = simd_float3x3(simd_float3(x: 1, y: 0, z: 0),
simd_float3(x: 1, y: 0, z: 0),
simd_float3(x: 1, y: 0, z: 0))
let matrix4x4 = simd_float4x4(simd_float4(x: 1, y: 0, z: 0,w: 0),
simd_float4(x: 1, y: 0, z: 0,w: 0),
simd_float4(x: 1, y: 0, z: 0,w: 0),
simd_float4(x: 1, y: 0, z: 0,w: 0))
swift
var m11 = 0 , m12 = 0 , m13 = 0 , m14 = 0 , m21 = 0 , m22 = 0 ,m23 = 0 , m24 = 0 , m31 = 0 , m32 = 0 , m33 = 0 , m34 = 0 , m41 = 0 , m42 = 0 , m43 = 0 , m44 = 0
// 矩阵是一个二维数组,用于表示和操作空间中的变换
//常用 4x4 矩阵表示 3D 空间中的变换(位置、旋转、缩放)
let f41 : simd_float4x4 = simd_float4x4(
simd_float4([ m11, m12, m13, m14 ]), // 第一列:描述 x 轴方向
simd_float4([ m21, m22, m23, m24 ]) , // 第二列:描述 y 轴方向
simd_float4([ m31, m32, m33, m34 ]) , // 第三列:描述 z 轴方向
simd_float4([ m41, m42, m43, m44 ]) 第四列:描述平移 (x, y, z)
)
//matrix_float4x4 也可以
/*
m41, m42, m43:表示平移(Translation),物体在 3D 空间中的位置
m44:通常为 1,用于保持线性变换
前三列 (m11-m33):表示旋转(Rotation)和缩放(Scale)。
*/
/*
矩阵类型,单位矩阵
[ 1, 0, 0, 0 ]
[ 0, 1, 0, 0 ]
[ 0, 0, 1, 0 ]
[ 0, 0, 0, 1 ]
无变换
在Arkit中表示就是
单位矩阵
*/
let identityMatrix = matrix_identity_float4x4
/*
平移
[ 1, 0, 0, tx ]
[ 0, 1, 0, ty ]
[ 0, 0, 1, tz ]
[ 0, 0, 0, 1 ]
*/
let tx:Float = 1.0,ty:Float = 1.0,tz:Float = 1.0
let translationMove = simd_float4x4(SCNMatrix4MakeTranslation(tx, ty, tz))
/*
用于改变物体的方向,通常分为绕 x、y、z 轴的旋转。
绕X轴旋转
[ 1, 0, 0, 0 ]
[ 0, cosθ, -sinθ, 0 ]
[ 0, sinθ, cosθ, 0 ]
[ 0, 0, 0, 1 ]
*/
let angle:Float = 1.0
let translationRotationX = simd_float4x4(SCNMatrix4MakeRotation(angle, 1, 0, 0))
/*
将矩阵的行与列交换
*/
let transposed = simd_transpose(f41)
/*
缩放矩阵
用于改变物体大小
[ sx, 0, 0, 0 ]
[ 0, sy, 0, 0 ]
[ 0, 0, sz, 0 ]
[ 0, 0, 0, 1 ]
*/
let sx:Float = 0.8,sy:Float = 0.7,sz:Float = 0.8
let translationScal = simd_float4x4(SCNMatrix4MakeScale(sx, sy, sz))
/*
组合矩阵 (Transform Matrix):
• 将平移、旋转、缩放组合成一个矩阵。
• 矩阵运算是非交换的,因此顺序重要。
*/
var anchor:ARAnchor?
let matrix:simd_float4x4! = anchor?.transform
//提取平移向量
let position = simd_make_float3(matrix.columns.3)
//获取方向 z轴方向
let zDirection = -simd_make_float3(matrix.columns.2)
/*
创建自定义矩阵
*/
//初始化单位矩阵
var transform_a = matrix_identity_float4x4
var v0:Float = 1.1
var v1:Float = 1.2
var v2:Float = 1.3
//设置位置
transform_a.columns.3 = simd_float4(v0, v1, v2, 1)
/*
ar中常用的
*/
var scenceView:ARSCNView?
let frame:ARFrame! = scenceView?.session.currentFrame
let cameraTransform:simd_float4x4 = frame.camera.transform
//获取camera的位置
let cameraPosition:simd_float3 = simd_make_float3(cameraTransform.columns.3)
print("\(cameraPosition.x),\(cameraPosition.y),\(cameraPosition.z)")
/*
将多个变换叠加
使用 simd_mul
*/
let wordTransform1 = simd_mul(translationMove, translationScal)
/*
矩阵逆
用于取消某个变换
simd_inverse
*/
let inverseMatrix = simd_inverse(matrix)