我决定学习一些关于矩阵和 3D 相机的知识,并为自己做了一些教育项目,以了解它是如何工作的。因为Swift和SwiftUI我有点熟悉。但问题更偏向于数学。
y 轴和 z 轴看起来很棒。
这是我的旋转和相机矩阵:
extension Matrix {
static func rotateX(_ angle: CGFloat) -> Matrix
{
Matrix([
[ 1, 0, 0, 0],
[ 0, cos(angle), sin(angle), 0],
[ 0, sin(angle), cos(angle), 0],
[ 0, 0, 0, 1 ]
])
}
static func rotateY(_ angle: CGFloat) -> Matrix
{
Matrix([
[ cos(angle), 0,sin(angle), 0],
[ 0, 1, 0, 0],
[ -sin(angle), 0, cos(angle), 0],
[ 0, 0, 0, 1 ],
])
}
static func rotateZ(_ angle: CGFloat) -> Matrix
{
Matrix([
[ cos(angle), sin(angle), 0, 0],
[-sin(angle), cos(angle), 0, 0],
[ 0, 0, 1, 0],
[ 0, 0, 0, 1 ]
])
}
static func rotate(_ p: Point3D) -> Matrix {
Matrix.rotateZ(p.z)
° .rotateY(p.y)
° .rotateX(p.x)
}
static func reverseZ() -> Matrix {
Matrix([
[ 1, 0, 0, 0],
[ 0, 1, 0, 0],
[ 0, 0, -1, 0],
[ 0, 0, 0, 1 ]
])
}
static func setWtoZ() -> Matrix {
Matrix([
[ 1, 0, 0, 0],
[ 0, 1, 0, 0],
[ 0, 0, -1, -1],
[ 0, 0, 0, 0 ]
])
}
static func projectionMatrix(fov: CGFloat, near: CGFloat, far: CGFloat) -> Matrix {
let scale = 1 / tan(fov/2.0 * CGFloat.pi / 180.0)
let r = Matrix([
[ scale, 0, 0, 0],
[ 0, scale, 0, 0],
[ 0, 0, -far / (far - near), -1],
[ 0, 0, -(far * near / (far - near)), 0 ]
])
return r
}
static func camera(fov: CGFloat, near: CGFloat, far: CGFloat) -> Matrix {
Self.reverseZ()
° setWtoZ()
° projectionMatrix(fov: fov, near: near, far: far)
}
}
这就是我如何称呼他们来获得所有必要的转变:
var result = point3d.matrix
° .rotate(objectRotation)
° .translate(by: objectTranslation)
° .translateToCamera(position: viewPosition)
° .camera(fov: fov, near: near, far:far)
我使用
SwiftMatrix
矩阵包。 °
符号表示矩阵乘法。也许我错了,但我怀疑熟悉 3D 的人可以立即发现错误。我不能。
知识主要来自本站
Y 和 Z 表现良好:
您的
func rotateX
中的矩阵似乎缺少其中一个sin(angle)
的减号。