transform的结构如下:
struct CATransform3D
{
  CGFloat m11, m12, m13, m14;
  CGFloat m21, m22, m23, m24;
  CGFloat m31, m32, m33, m34;
  CGFloat m41, m42, m43, m44;
};

首先要实现view(layer)的透视效果(就是近大远小),是通过设置m34的:

CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / -500;

m34负责z轴方向的translation(移动),m34= -1/D,  默认值是0,也就是说D无穷大,这意味layer in projection plane(投射面)和layer in world coordinate重合了。

D越小透视效果越明显。

所谓的D,是eye(观察者)到投射面的距离。

概述

在iOS中使用CATransform3D这个结构体来表示三维的齐次坐标变换矩阵. 齐次坐标是一种坐标的表示方法,n维空间的坐标需要用n+1个元素的坐标元组来表示,在Quartz 2D Transform中就有关于齐次坐标的应用,那边是关于二维空间的变换,其某点的齐次坐标的最后一个元素始终设置为1。使用齐次坐标而不是简单的数学坐标是为了方便图形进行仿射变换,仿射变换可以通过仿射变换矩阵来实现,3D的仿射变换可以实现诸如 平移(translation),旋转(rotation),缩放(scaling),切变(shear)等变换。如果不用齐次坐标那么进行坐标变换可能就涉及到两种运算了,加法(平移)和乘法(旋转,缩放),而使用齐次坐标以及齐次坐标变换矩阵后只需要矩阵乘法就可以完成一切了。上面的这些如果需要深入了解就需要去学习一下图形变换的相关知识,自己对矩阵的乘法进行演算。

iOS中的CALayer的3D本质上并不能算真正的3D(其视点即观察点或者所谓的照相机的位置是无法变换的),而只是3D在二维平面上的投影,投影平面就是手机屏幕也就是xy轴组成的平面(注意iOS中为左手坐标系),那么视点的位置是如何确定的呢?可以通过CATransform3D中的m34来间接指定, m34 = -1/z,其中z为观察点在z轴上的值,而Layer的z轴的位置则是通过anchorPoint来指定的,所谓的anchorPoint(锚点)就是在变换中保持不变的点,也就是某个Layer在变换中的原点,xyz三轴相交于此点。在iOS中,Layer的anchorPoint使用unit coordinate space来描述,unit coordinate space无需指定具体真实的坐标点而是使用layer bounds中的相对位置,下图展示了一个Layer中的几个特殊的锚点, 

m34 = -1/z中,当z为正的时候,是我们人眼观察现实世界的效果,即在投影平面上表现出近大远小的效果,z越靠近原点则这种效果越明显,越远离原点则越来越不明显,当z为正无穷大的时候,则失去了近大远小的效果,此时投影线垂直于投影平面,也就是视点在无穷远处,CATransform3D中m34的默认值为0,即视点在无穷远处.

还有一个需要说明一下的就是齐次坐标到数学坐标的转换 通用的齐次坐标为 (a, b, c, h),其转换成数学坐标则为 (a/h, b/h, c/h).

代数解释

假设一个Layer anchorPoint为默认的 (0.5, 0.5 ), 其三维空间中一个A点 (6, 0, 0),m34 = -1/1000.0, 则此点往z轴负方向移动10个单位之后,则在投影平面上看到的点的坐标是多少呢?

A点使用齐次坐标表示为 (6, 0, 0, 1)

QuartzCore框架为我们提供了函数来算出所需要的矩阵,

    CATransform3D transform = CATransform3DIdentity; transform.m34 = -1/1000.0; transform = CATransform3DTranslate(transform, 0, 0, -10); 

计算出来的矩阵为


{ 1,    0, 0, 0; 0, 1, 0, 0; 0, 0, 1, -0.001; 0, 0, -10, 1.01; } 

其实上面的变换矩阵本质上是两个矩阵相乘得到的 变换矩阵 * 投影矩阵 变换矩阵为

{1,    0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, -10, 1; } 

投影矩阵为


{1,    0, 0, 0; 0, 1, 0, 0; 0, 0, 1, -0.001; 0, 0, 0, 1; } 

上面的两个矩阵相乘则会得到最终的变换矩阵(如果忘记矩阵乘法的可以去看下线性代数复习下),所以一个矩阵就可以完成变换和投影。

将A点坐标乘上最终的变换矩阵,则得到 {6, 0 , -10, 1.01}, 转换成数学坐标点为 {6/1.01, 0, 10/1.01},则可以知道其在投影平面上的投影点为 {6/1.01, 0, 0} 也就是我们看到的变换后的点。其比之前较靠近原点。越往z轴负方向移动,则在投影平面上越靠近原点。

几何解释

将上面的例子使用几何的方式来进行解释分析,当我们沿着y轴的正方向向下看时候,可以得到如下的景象

虚线为投影线,其和x轴的交点即为A点的投影点。 由相似三角形的定理我们很容易算出投影的点,

1000/(1000 + 10) = x/6,则x = 6*1000/1010 = 6/1.01

转载于:https://www.cnblogs.com/OIMM/p/5205528.html

iOS动画 三维透视投影 m34相关推荐

  1. iOS的三维透视投影

    transform的结构如下: struct CATransform3D {   CGFloat m11, m12, m13, m14;   CGFloat m21, m22, m23, m24;   ...

  2. 系统学习iOS动画之六:3D动画

    本文是我学习<iOS Animations by Tutorials> 笔记中的一篇. 文中详细代码都放在我的Github上 andyRon/LearniOSAnimations. 到目前 ...

  3. iOS动画专题·UIView二维形变动画与CAAnimation核心动画

    点击上方"iOS开发",选择"置顶公众号" 关键时刻,第一时间送达! 1. iOS动画 总的来说,从涉及类的形式来看,iOS动画有:基于UIView的仿射形变动 ...

  4. iOS 动画专题(UIView二维形变动画与CAAnimation核心动画)

    文章目录 1. iOS动画 2. UIView动画 2.1 设置UIView动画的两种语法形式 2.2 设置属性形变动画的两种类型 2.3 与动画相关的属性 2.3.1 UIView与动画相关的属性- ...

  5. iOS 动画原理与实现--帧动画、逐帧动画、CALayer

    这篇文章不会教大家如何实现一个具体的动画效果,我会从动画的本质出发,来说说 iOS 动画的原理与实现方式. 什么是动画 动画,顾名思义,就是能"动"的画. 人的眼睛对图像有短暂的记 ...

  6. 解析 iOS 动画原理与实现

    什么是动画 动画,顾名思义,就是能"动"的画. 人的眼睛对图像有短暂的记忆效应,所以当眼睛看到多张图片连续快速的切换时,就会被认为是一段连续播放的动画了. 比如,中国古代的&quo ...

  7. iOS动画系列之八:使用CAShapeLayer绘画动态流量图

    这篇文章通过使用CAShapeLayer和UIBezierPath来画出一个动态显示剩余流量的小动画. 最终实现的效果如下: Paste_Image.png 动态效果图: shapeLayerAni. ...

  8. iOS动画系列之九:实现点赞的动画及播放起伏指示器

    iOS动画系列,共十篇.现在写到第九篇啦.感兴趣的可以通过下面的传输门进到其他几篇文章里面. 第一篇:iOS动画系列之一:通过实战学习CALayer和透视的原理.做一个带时分秒指针的时钟动画(上) 第 ...

  9. iOS动画详解(学习动画看这一篇就够了)

    2019独角兽企业重金招聘Python工程师标准>>> 原文出处:wu大维 动效设计一直是iOS平台的优势,良好的动效设计可以很好地提升用户体验.而动画则是动效的基础支撑.本动画将从 ...

最新文章

  1. ios浏览器不支持onblur事件
  2. mybatis 中 foreach collection的三种用法
  3. mysql dw解决方案_MySQL 的 DW 解决方案(MySQL + Infobright)
  4. 谓词::不适合Java
  5. 机器学习笔记(七)——决策树模型
  6. Activiti工作流之事件监听详解-ActivitiEventListener
  7. 网页加载速度优化方案
  8. java报错 csrf_CSRF Security Error解决办法
  9. 手机黑圆点怎么打_两个字中间的圆点怎么打?黑色圆点符号怎么打出来?
  10. 图解LeetCode——854. 相似度为 K 的字符串(难度:困难)
  11. 生活娱乐 重庆乡村基挑战肯德基为何失败
  12. MarkDown图片居中
  13. navicat 解析sql_使用 Navicat 查询分析器优化查询性能(第 1 部分)
  14. 从零开始制作游戏辅助
  15. PHP7.2源码安装
  16. 【iOS】Web Color 的 OC 实现
  17. 深入浅出地理解机器人手眼标定
  18. 纠错技术之FEC(向前纠错)
  19. 读《骨干是折腾出来的》有感
  20. Spring boot 解析mp4格式视频交给前端进行播放

热门文章

  1. 一个小例子介绍Obj-C的函数命名方式
  2. Google 发布最新 IDC 能源消耗报告
  3. SQL.H 通过此文件寻找sqlAPI编程的一种捷径
  4. OAuth2.0_JWT令牌介绍_Spring Security OAuth2.0认证授权---springcloud工作笔记147
  5. EJB3.0异常总结---Exception in thread “main“ javax.naming.NameNotFoundException: StatelessEjbBean not bou
  6. GraphChi: Large-Scale Graph Computation on Just a PC
  7. django 集成个推_Django动态添加定时任务之djangocelery的使用
  8. 随想录(虚拟机实现)
  9. js 给服务器发消息,的Node.js:发送消息至服务器
  10. ajax get 缓存 ie,Ajax异步同步请求被IE缓存的问题解决方法(get方式)