`
啸笑天
  • 浏览: 3435058 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

CATransform3D

阅读更多

CATransform3D 的数据结构定义了一个同质的三维变换(4x4 CGFloat值的矩阵),用于图层的旋转,缩放,偏移,歪斜和应用的透视。

图层的2个属性指定了变换矩阵:transform 和 sublayerTransform。

transform : 是结合 anchorPoint(锚点)的位置来对图层和图层上的子图层进行变化。

sublayerTransform:是结合anchorPoint(锚点)的位置来对图层的子图层进行变化,不包括本身。

CATransform3DIdentity 是单位矩阵,该矩阵没有缩放,旋转,歪斜,透视。该矩阵应用到图层上,就是设置默认值。

 

初始化方法:CATransform3DMakeTranslation

官方文档:

Returns a transform that translates by '(tx, ty, tz)'. t' = [1 0 0 0; 0 1 0 0; 0 0 1 0; tx ty tz 1].

CATransform3D CATransform3DMakeTranslation (CGFloat tx, CGFloat ty, CGFloat tz)。

做一个解释,对于初学者来说,可能没有看明白是什么意思。我详细说下

对于CATransform3D来说,它是一个4x4 CGFloat的矩阵。

而上面给的值:[1 0 0 0; 0 1 0 0; 0 0 1 0; tx ty tz 1].

给竖起来后。就发现:

1    0    0    0

0    1    0    0

0    0    1    0

tx  ty   tz    1

竖起来看就很明显了。

CATransform3D 又是一个结构。他有自己的一个公式,可以进行套用。

struct CATransform3D

{

CGFloat    m11(x缩放),    m12(y切变),      m13(旋转),    m14();

CGFloat    m21(x切变),    m22(y缩放),      m23()       ,    m24();

CGFloat    m31(旋转)  ,    m32( )       ,      m33()       ,    m34(透视效果,要操作的这个对象要有旋转的角度,否则没有效果。正直/负值都有意义);

CGFloat    m41(x平移),    m42(y平移),    m43(z平移) ,    m44();

};

根据这个公式,就一目了然了。

CATransform3D CATransform3DMakeTranslation (CGFloat tx, CGFloat ty, CGFloat tz)

的参数意思就是

tx::x平移。  ty:y平移。  tz:z平移

 

换换函数:

CATransform3D CATransform3DMakeTranslation (CGFloat tx, CGFloat ty, CGFloat tz)

tx:X轴偏移位置,往下为正数。

ty:Y轴偏移位置,往右为正数。

tz:Z轴偏移位置,往外为正数。

例:

如果有2个图层,一个是绿色的,一个是红色的。先加载绿色,后加载红色。

tx,ty的左右偏移先不说了。

如果绿色的tz为-10 ,红色的tz为 0 效果如下:

 



 

 

如果绿色的tz为 0 ,红色的tz为-10 效果如下:

 



 

 

对于tz来说,值越大,那么图层就越往外(接近屏幕),值越小,图层越往里(屏幕里)。

CATransform3D CATransform3DTranslate (CATransform3D t, CGFloat tx, CGFloat ty, CGFloat tz);

t:就是上一个函数。其他的都一样。

就可以理解为:函数的叠加,效果的叠加。

CATransform3D CATransform3DMakeScale (CGFloat sx, CGFloat sy, CGFloat sz);

sx:X轴缩放,代表一个缩放比例,一般都是 0 --- 1 之间的数字。

sy:Y轴缩放。

sz:整体比例变换时,也就是m11(sx)== m22(sy)时,若m33(sz)>1,图形整体缩小,若0<1,图形整体放大,若m33(sz)<0,发生关于原点的对称等比变换。

当sx = 1,sy = 1时。如图:

 



 

 

当sx = 0.5,sy = 0.5时。如图:

 



 

 

CATransform3D CATransform3DScale (CATransform3D t, CGFloat sx, CGFloat sy, CGFloat sz)

t:就是上一个函数。其他的都一样。

就可以理解为:函数的叠加,效果的叠加。

CATransform3D CATransform3DMakeRotation (CGFloat angle, CGFloat x, CGFloat y, CGFloat z);

旋转效果。

angle:旋转的弧度,所以要把角度转换成弧度:角度 * M_PI / 180。

x:向X轴方向旋转。值范围-1 --- 1之间

y:向Y轴方向旋转。值范围-1 --- 1之间

z:向Z轴方向旋转。值范围-1 --- 1之间

例: 向X轴旋转60度。     

 



 

 

       向Y轴旋转60度。        

 



 

 

       向Z轴旋转60度。

 



 

 

向 X轴,Y轴都旋转60度,就是沿着对角线旋转。

 



 

 

可以通过X,Y,Z轴同时变化,来旋转图像。

CATransform3D CATransform3DRotate (CATransform3D t, CGFloat angle, CGFloat x, CGFloat y, CGFloat z);

t:就是上一个函数。其他的都一样。

就可以理解为:函数的叠加,效果的叠加。

CATransform3D CATransform3DInvert (CATransform3D t);

翻转效果。

未使用

 



 

 

使用

 



 

 

CGAffineTransform CATransform3DGetAffineTransform (CATransform3D t);

bool CATransform3DIsAffine (CATransform3D t);

仿射效果。

就是把一个 CATransform3D 对象转换成一个 CGAffineTransform 对象。

也就是把 CATransform3D 矩阵 转换成 CGAffineTransform 矩阵

变换函数同时提供了可以比较一个变换矩阵是否是单位矩阵,或者两个矩阵是否相等。

bool CATransform3DIsIdentity (CATransform3D t);

bool CATransform3DEqualToTransform (CATransform3D a, CATransform3D b);

也可以通过修改数据结构和键值来设置变换效果。

struct CATransform3D

{

CGFloat m11, m12, m13, m14

CGFloat m21, m22, m23, m24

CGFloat m31, m32, m33, m34

CGFloat m41, m42, m43, m44

}

可以直接修改 其中的一个值,来达到相同的效果。

或者修改键值

[myLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"transform.rotation.x"];

 



 

 

 

一些属性:

 

上面的左右旋转,看起来图层并没有被旋转,而是仅仅在水平方向上的一个压缩,是哪里出了问题呢?

其实完全没错,视图看起来更窄实际上是因为我们在用一个斜向的视角看它,而不是透视

 

 

 

+

透视投影

在真实世界中,当物体远离我们的时候,由于视角的原因看起来会变小,理论上说远离我们的视图的边要比靠近视角的边跟短,但实际上并没有发生,而我们当前的视角是等距离的,也就是在3D变换中任然保持平行,和之前提到的仿射变换类似。

在等距投影中,远处的物体和近处的物体保持同样的缩放比例,这种投影也有它自己的用处(例如建筑绘图,颠倒,和伪3D视频),但当前我们并不需要。

为了做一些修正,我们需要引入投影变换(又称作z变换)来对除了旋转之外的变换矩阵做一些修改,Core Animation并没有给我们提供设置透视变换的函数,因此我们需要手动修改矩阵值,幸运的是,很简单:

CATransform3D的透视效果通过一个矩阵中一个很简单的元素来控制:m34m34(图5.9)用于按比例缩放X和Y的值来计算到底要离视角多远。



 

图5.9 CATransform3Dm34元素,用来做透视

m34的默认值是0,我们可以通过设置m34为-1.0 / d来应用透视效果,d代表了想象中视角相机和屏幕之间的距离,以像素为单位,那应该如何计算这个距离呢?实际上并不需要,大概估算一个就好了。

因为视角相机实际上并不存在,所以可以根据屏幕上的显示效果自由决定它的防止的位置。通常500-1000就已经很好了,但对于特定的图层有时候更小后者更大的值会看起来更舒服,减少距离的值会增强透视效果,所以一个非常微小的值会让它看起来更加失真,然而一个非常大的值会让它基本失去透视效果,对视图应用透视的代码见清单5.5,结果见图5.10。

1

 

清单5.5 对变换应用透视效果

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    //create a new transform
    CATransform3D transform = CATransform3DIdentity;
    //apply perspective
    transform.m34 = - 1.0 / 500.0;
    //rotate by 45 degrees along the Y axis
    transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);
    //apply to layer
    self.layerView.layer.transform = transform;
}

@end

 

灭点

当在透视角度绘图的时候,远离相机视角的物体将会变小变远,当远离到一个极限距离,它们可能就缩成了一个点,于是所有的物体最后都汇聚消失在同一个点。

在现实中,这个点通常是视图的中心(图5.11),于是为了在应用中创建拟真效果的透视,这个点应该聚在屏幕中点,或者至少是包含所有3D对象的视图中点。



 

图5.11 灭点

Core Animation定义了这个点位于变换图层的anchorPoint(通常位于图层中心,但也有例外,见第三章)。这就是说,当图层发生变换时,这个点永远位于图层变换之前anchorPoint的位置。

当改变一个图层的position,你也改变了它的灭点,做3D变换的时候要时刻记住这一点,当你视图通过调整m34来让它更加有3D效果,应该首先把它放置于屏幕中央,然后通过平移来把它移动到指定位置(而不是直接改变它的position),这样所有的3D图层都共享一个灭点。

 

 

sublayerTransform属性

如果有多个视图或者图层,每个都做3D变换,那就需要分别设置相同的m34值,并且确保在变换之前都在屏幕中央共享同一个position,如果用一个函数封装这些操作的确会更加方便,但仍然有限制(例如,你不能在Interface Builder中摆放视图),这里有一个更好的方法。

CALayer有一个属性叫做sublayerTransform。它也是CATransform3D类型,但和对一个图层的变换不同,它影响到所有的子图层。这意味着你可以一次性对包含这些图层的容器做变换,于是所有的子图层都自动继承了这个变换方法。

相较而言,通过在一个地方设置透视变换会很方便,同时它会带来另一个显著的优势:灭点被设置在容器图层的中点,从而不需要再对子图层分别设置了。这意味着你可以随意使用positionframe来放置子图层,而不需要把它们放置在屏幕中点,然后为了保证统一的灭点用变换来做平移。

 

thx:

https://zsisme.gitbooks.io/ios-/content/chapter5/3d-transform.html

http://www.jianshu.com/p/69ba0a4b2df9

http://www.jianshu.com/p/9cbf52eb39dd

http://www.jianshu.com/p/272aa1f26c62

iOS的三维透视投影

  • 大小: 244 Bytes
  • 大小: 241 Bytes
  • 大小: 8.4 KB
  • 大小: 4.3 KB
  • 大小: 9.8 KB
  • 大小: 9.8 KB
  • 大小: 47.9 KB
  • 大小: 18.9 KB
  • 大小: 47.9 KB
  • 大小: 44.9 KB
  • 大小: 58.5 KB
  • 大小: 148.5 KB
  • 大小: 47.7 KB
分享到:
评论

相关推荐

    CATransform3D中m34值的测试

    CATransform3D中m34值的设定一直不太理解。工作中用到就好好学习了下。原来m34值必须是在 在绕x轴旋转或y轴旋转后,才会有效果,否则是看不出效果的。 而且如下,m34的设置必须在旋转之前才有效。例子很简单,象试...

    CATransform3D Document

    CATransform3D Document 苹果开发者网站上的文档,分享~

    CATransform3D操作变得容易。-Swift开发

    操纵和使用CATransform3D进行动画和交互非常具有挑战性……分解使得CATransform3D,matrix_double4x4和matrix_float4x4更加易于使用。 分解操纵并使用CATransform3D进行动画和交互非常具有挑战性……分解使...

    TransformDemo:iOS 3D CATransform3D演示

    TransformDemoiOS 3D CATransform3D demo透视设置 CATransform3D.m34=-1/D D越小 效果越明显 (m34 float)设置m34后,旋转才有效

    详解iOS的Core Animation框架中的CATransform3D图形变换

    CATransform3D定义了一个变化矩阵,通过对矩阵参数的设置,我们可以改变layer的一些属性,这个属性的改变,可以产生动画的效果。 CATransform3D CATransform3DMakeTranslation (CGFloat tx, CGFloat ty, CGFloat tz)...

    ios-CATransform3D_Demo.zip

    模仿"物色"视图动画,特别鸣谢 ... //临时效果, 后期如有好的想法会继续添加功能. (如果有您有更好的实现方式请留言告知,O(∩_∩)O谢谢 ) https://github.com/wangjianquan/CATransform3D_Demo.git

    PerspectiveTransform:计算两个透视图之间的CATransform3D

    可以使用Core Animation CATransform3D和在给定的图像视觉角度内放置视图。 假设源角和目标角为,则在四个角定义的源角和目标角之间计算投影。 要将重叠图像放置在具有匹配透视图的容器图像顶部,我们可以使用Core...

    SwiftTransforms:给CGAffineTransform和CATransform3D他们应有的爱

    迅捷变换 因为CGAffineTransform和CATransform3D应该得到相同的结果 :sparkling_heart: 作为CGRect和朋友。

    分解:简化了CATransform3D操作

    操纵和使用CATransform3D进行动画和交互非常具有挑战性……分解使得CATransform3D , matrix_double4x4和matrix_float4x4更加易于使用。 注意:用于分解的API仍在大量更改/优化中,因此请随时提供反馈,并期望随着...

    CATransform3D动画效果

    该源码案例是一款不错的CATransform3D动画效果,源码CATransform,CATransform3D动画效果。 测试环境:Xcode 6.2,iOS 6.0以上

    简单的3D动画效果

    3d 动画 ios CATransform3D

    ios-Cell动态变化.zip

    上拉下拉 tableView时 cell 会发生动态变化 添加 CATransform3D 动画 几行代码 实现效果

    JS.Labs.transform:CSS3 3D 变换游乐场

    CATransform3D输出的基础(已经用m11表示法组成) 一些基本功能( translate 、 rotateX等) CSS 输出( matrix3d();编辑器 UI 的输出) 0.7.0 新的类层次结构 EPPZ视图 场景 将合并到 eppz!js 中的很棒的助手 ...

    仿淘宝选择规格效果

    作者vaithwee,源码iOS-Code-4-App,这里搜集了一些日常工作中的会使用的代码或者基础知识,基础才是最重要,对于程序员来说,没有什么...利用简单的CATransform3D实现对于底部视图的缩放,并且弹出自己需要的Pop视图

    仿淘宝选择规格效果iOS(Swift)

    利用简单的CATransform3D实现对于底部视图的缩放,并且弹出自己需要的Pop视图 对于这个效果,主要需要的是对底部的视图进行缩放。对此,我们获取到当前Window的RootViewController,然后对其的View进行两步动画...

    iOS实现折叠图片

    1.CATransform3D 做3D转换,用来实现图片折叠时的立体感。 2.animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion: 回弹效果,duanger~ 3.CAGradientLayer ...

    ios 3d向上翻开效果例子

    ios 3d向上翻开效果例子 用CATransform3DMakeRotation实现沿x轴向上翻开效果. 压缩包是在在imac下压缩的。

    IOS 实现3D 浮动效果动画

    CATransform3DRotate 转换坐标系 整体视图的层级结构 tvOSCardView cardImageView cardParallaxView 转换坐标系的代码 CGFloat xFactor = MIN(1, MAX(-1, (touchPoint.x - (self.bounds.size.width / 2)) / ...

Global site tag (gtag.js) - Google Analytics