结构CATransform3D的m34是什么意思,我只知道可以改变视角,但是-0.001和0.001的值是什么意思呢?
3 回答
您可以在此处找到完整的详细信息。请注意,Apple 使用反向乘法顺序进行投影(相对于给定链接),因此所有矩阵乘法都被反转并且所有矩阵都被转置。
含义的简短描述:
- m34 = 1/z 到投影平面的距离(参考链接中的 1/e z项)
- + 因为 z 轴朝向观察者,使用时会产生“照镜子”的感觉 -
- 投影中心为 (0,0,0) 加上您设置的任何翻译
我的解决方案在这里:
实体:
eye
- 从屏幕到眼睛的距离scale
- 变换对象的视觉比例distance
- 到变换对象的距离
连接公式:
scale = eye / (eye + distance)
distance = eye * (1.0/scale - scale)
eye = distance / (1.0/scale - scale)
为选定的眼距缩小比例计算 z 距离的示例:
CATransform3D transformByScaleAndEye(CGFloat scale, CGFloat eye) {
CATransform3D t = CATransform3DIdentity;
t.m34 = -1.0 / eye;
CGFloat distance = -eye*(1.0/scale - scale);
return CATransform3DTranslate(t, 0, 0, distance);
}
以下是一些我认为读者在回答问题之前应该了解的主题的背景知识:
iOS 坐标系:想象你正垂直握住手机,屏幕正对着你。对于每个视图,其坐标系的原点位于其中心。x 轴从左到右,y 轴从上到下,z 轴从手机背面到您的脸。
齐次坐标:使用 iOS 进行 3D 变换时,您使用的是齐次坐标或投影坐标,而不是传统的笛卡尔坐标。简而言之,新坐标系
w
比旧坐标系多使用一维。这个系统的美妙之处在于它允许通过向量矩阵乘法来进行旋转/平移/缩放。
要将齐次坐标中的向量转换为 Catersian 坐标,请将 x、y、z 除以 w。
现在,让我们来看看答案。考虑如下示例:
var transform = CATransform3DIdentity
transform.m34 = -1 / 500
transform = CATransform3DRotate(transform, Double.pi/4, 0, 1, 0)
transform = CATransform3DTranslate(transform, 0, 0, 200)
imageLayer.transform = transform
要知道上面的代码是做什么的,您必须以相反的顺序阅读它。首先,图像在 z 轴方向上移动 200 像素(正号表示其方向是从屏幕朝向您的脸部)。其次,图像相对于 y 轴旋转 45 度(向右倾斜)。如果您停在这里,您将看到一个宽度较小并向右移动的图像。但是一些操作是在第 3 步完成的,并且“神奇地”给出了图像透视图。m34
元素的奥秘就在这里。
这是用矩阵乘法表示的操作序列:
[x' y' z' w'] = ([x y z w] * translation_matrix * rotation_matrix) * perspective_matrix
透视矩阵变换
现在,专注于操作perspective_matrix
转换为 Catersian 坐标:
使用比例因子进行转换
要在 2D 屏幕上模拟 3D 透视,您希望靠近眼睛的物体看起来比远离眼睛的物体更大。为此,您将对象从 3D 空间投影到屏幕上,即从您的眼睛中画出穿过对象并与屏幕截取的假想线。让我们计算该投影的比例因子:
z = the object's z-coordinate which is its distance to the screen
eye2screen #distance from your eyes to the screens
scaleFactor = eye2screen / (eye2Screen - z) #Thales's intercept theorem
快速计算可以证实我们的直觉。随着 z 变小(即物体远离眼睛),scaleFactor
变小。
scaleFactor
用perspective_matrix
上面的乘法调和我们有:
scaleFactor = 1 / (1 + m34 * z)
1 / (1 - z / eye2screen) = 1 / (1 + m34 * z)
-1 / eye2screen = m34
m34 = -1 / eye2screen
在眼睛和屏幕之间选择一个合理的距离(比如 500),你可以计算出 m34,你就得到了一个新的perspective_matrix
.
结论:
- 透视矩阵是一种数学技巧,可以根据对象与您眼睛的距离来缩放对象。
- 计算
m34 = -1 / eye2screen
给你一个perspective_matrix
perspective_matrix
操作只能在转换管道结束时应用一次。