`
啸笑天
  • 浏览: 3462052 次
  • 性别: 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文档详解** 在iOS开发中,`CATransform3D`是Core Animation框架中的一个关键数据类型,用于表示3D变换。它提供了对层(CALayer)进行旋转、平移、缩放和剪切等复杂3D图形操作的能力。苹果开发者网站...

    TransformDemo:iOS 3D CATransform3D演示

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

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

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

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

    在iOS和macOS开发中,`CGAffineTransform`和`CATransform3D`是两个非常重要的类,它们用于处理2D和3D图形变换。在本项目“SwiftTransforms”中,开发者旨在提供一个方便、统一的方式来处理这两种变换,使得它们能够...

    详解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

    CATransform3D动画效果

    本案例"CATransform3D动画效果"展示了如何利用CATransform3D在iOS应用中实现精美的3D动画。 首先,CATransform3D是一个4x4的矩阵,用于描述对象在3D空间中的位置、旋转、缩放和透视。通过调整这个矩阵的各个元素,...

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

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

    分解:简化了CATransform3D操作

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

    简单的3D动画效果

    本教程将探讨如何在iOS应用中实现“简单的3D动画效果”,主要聚焦于`CATransform3D`这一核心概念。 首先,`CATransform3D`是Core Animation框架中的一个结构体,用于表示3D变换。它提供了对对象进行旋转、平移、...

    ios源码之3D书本翻页效果.rar

    为了实现3D翻页效果,我们需要创建两个连续的CALayer,分别代表书的两页,然后使用CATransform3D来改变其3D空间中的位置和旋转角度,模拟翻页的动作。 关键知识点二:CATransform3D CATransform3D是一个用于表示3D...

    IOS_3D_UI的例子

    这个属性是一个`CATransform3D`结构体,它定义了一个4x4的矩阵,用于描述2D或3D空间中的几何变换,包括平移、旋转、缩放等操作。在iOS中,`CATransform3D`提供了一种优雅的方式,使得我们可以轻松地为界面元素添加...

    ios实现超炫3d界面切换

    在动画块内,可以设置视图的`transform`属性,将其转换为`CATransform3D`类型,然后应用3D旋转或其他变换。 4. **UIPageViewController**: 如果需要实现类似书本翻页的效果,可以使用`UIPageViewController`。它...

    ios-3d轮播.zip

    4. **利用CATransform3D**:为了实现3D旋转,我们需要为每个子视图应用CATransform3D。核心变换包括`CATransform3DRotate`和`CATransform3DScale`,它们分别控制旋转和缩放。通常,中间的视图保持正常大小,而其他...

    iOS 3D星球效果demo

    4. **CALayer和CATransform3D**:Core Animation的CALayer可以使用CATransform3D来应用3D变换,包括旋转、缩放和位移,从而实现星球的滚动效果。通过巧妙地调整这些变换,可以模拟出星球在3D空间中的运动。 5. **...

    ios-3D 效果-球.zip

    在iOS中实现3D效果通常需要利用Core Animation框架,特别是CALayer类,它可以创建和管理2D图形层,但也可以通过CATransform3D来实现3D变换。这些变换包括旋转、缩放、平移等,对于创建3D球体效果至关重要。可能的...

    ios-collectionView实现3D滚动图片效果.zip

    2. **应用CATransform3D**: 使用Core Animation的3D变换属性CATransform3D来设置每个单元格的视图变换。这通常包括旋转和平移,使得在滚动过程中产生立体感。 3. **视差效果**: 考虑到视差效应,近处的单元格会比...

Global site tag (gtag.js) - Google Analytics