CGAffineTransformMake(a,b,c,d,tx,ty) 矩阵运算的原理

简记:

CGAffineTransformMake(a,b,c,d,tx,ty)

ad缩放bc旋转tx,ty位移,基础的2D矩阵

公式

x=ax+cy+tx
    y=bx+dy+ty

1.矩阵的基本知识:

struct CGAffineTransform

{
  CGFloat a, b, c, d;
  CGFloat tx, ty;
};

CGAffineTransform CGAffineTransformMake (CGFloat a,CGFloat b,CGFloat c,CGFloat d,CGFloat tx,CGFloat ty);

为了把二维图形的变化统一在一个坐标系里,引入了齐次坐标的概念,即把一个图形用一个三维矩阵表示,其中第三列总是(0,0,1),用来作为坐标系的标准。所以所有的变化都由前两列完成。

以上参数在矩阵中的表示为:

|a    b    0|

|c    d    0|

|tx   ty   1|

运算原理:原坐标设为(X,Y,1);

|a    b    0|

[X,Y,  1]      |c    d    0|     =     [aX + cY + tx   bX + dY + ty  1] ;

|tx    ty  1|

通过矩阵运算后的坐标[aX + cY + tx   bX + dY + ty  1],我们对比一下可知:

第一种:设a=d=1, b=c=0.  

[aX + cY + tx   bX + dY + ty  1] = [X  + tx  Y + ty  1];

可见,这个时候,坐标是按照向量(tx,ty)进行平移,其实这也就是函数

CGAffineTransform CGAffineMakeTranslation(CGFloat tx,CGFloat ty)的计算原理。

第二种:设b=c=tx=ty=0.  

[aX + cY + tx   bX + dY + ty  1] = [aX    dY   1];

可见,这个时候,坐标X按照a进行缩放,Y按照d进行缩放,a,d就是X,Y的比例系数,其实这也就是函数

CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)的计算原理。a对应于sx,d对应于sy。

第三种:设tx=ty=0,a=cos?,b=sin?,c=-sin?,d=cos?。

[aX + cY + tx   bX + dY + ty  1] = [Xcos? - Ysin?    Xsin? + Ycos?  1] ;

可见,这个时候,?就是旋转的角度,逆时针为正,顺时针为负。其实这也就是函数

CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle)的计算原理。angle即?的弧度表示。

2.利用上面的变换写一个UIImage矩阵变换的例子:

下面是一个关于image的矩阵运算的例子,无外乎是运用以上三种变换的组合,达到所定义的效果

Java代码  

    1. //UIImageOrientation的定义,定义了如下几种变换
    2. typedef enum
    3. {
    4. UIImageOrientationUp,            // default orientation
    5. UIImageOrientationDown,          // 180 deg rotation
    6. UIImageOrientationLeft,          // 90 deg CCW
    7. UIImageOrientationRight,         // 90 deg CW
    8. UIImageOrientationUpMirrored,    // as above but image mirrored along other axis. horizontal flip
    9. UIImageOrientationDownMirrored,  // horizontal flip
    10. UIImageOrientationLeftMirrored,  // vertical flip
    11. UIImageOrientationRightMirrored, // vertical flip
    12. } UIImageOrientation;
    13. //按照UIImageOrientation的定义,利用矩阵自定义实现对应的变换;
    14. -(UIImage *)transformImage:(UIImage *)aImage
    15. {
    16. CGImageRef imgRef = aImage.CGImage;
    17. CGFloat width = CGImageGetWidth(imgRef);
    18. CGFloat height = CGImageGetHeight(imgRef);
    19. CGAffineTransform transform = CGAffineTransformIdentity;
    20. CGRect bounds = CGRectMake(0, 0, width, height);
    21. CGFloat scaleRatio = 1;
    22. CGFloat boundHeight;
    23. UIImageOrientation orient = aImage.imageOrientation;
    24. switch(UIImageOrientationLeftMirrored)
    25. {
    26. case UIImageOrientationUp:
    27. transform = CGAffineTransformIdentity;
    28. break;
    29. case UIImageOrientationUpMirrored:
    30. transform = CGAffineTransformMakeTranslation(width, 0.0);
    31. transform = CGAffineTransformScale(transform, -1.0, 1.0); //沿y轴向左翻
    32. break;
    33. case UIImageOrientationDown:
    34. transform = CGAffineTransformMakeTranslation(width, height);
    35. transform = CGAffineTransformRotate(transform, M_PI);
    36. break;
    37. case UIImageOrientationDownMirrored:
    38. transform = CGAffineTransformMakeTranslation(0.0, height);
    39. transform = CGAffineTransformScale(transform, 1.0, -1.0);
    40. break;
    41. case UIImageOrientationLeft:
    42. boundHeight = bounds.size.height;
    43. bounds.size.height = bounds.size.width;
    44. bounds.size.width = boundHeight;
    45. transform = CGAffineTransformMakeTranslation(0.0, width);
    46. transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
    47. break;
    48. case UIImageOrientationLeftMirrored:
    49. boundHeight = bounds.size.height;
    50. bounds.size.height = bounds.size.width;
    51. bounds.size.width = boundHeight;
    52. transform = CGAffineTransformMakeTranslation(height, width);
    53. transform = CGAffineTransformScale(transform, -1.0, 1.0);
    54. transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
    55. break;
    56. case UIImageOrientationRight: //EXIF = 8
    57. boundHeight = bounds.size.height;
    58. bounds.size.height = bounds.size.width;
    59. bounds.size.width = boundHeight;
    60. transform = CGAffineTransformMakeTranslation(height, 0.0);
    61. transform = CGAffineTransformRotate(transform, M_PI / 2.0);
    62. break;
    63. case UIImageOrientationRightMirrored:
    64. boundHeight = bounds.size.height;
    65. bounds.size.height = bounds.size.width;
    66. bounds.size.width = boundHeight;
    67. transform = CGAffineTransformMakeScale(-1.0, 1.0);
    68. transform = CGAffineTransformRotate(transform, M_PI / 2.0);
    69. break;
    70. default:
    71. [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
    72. }
    73. UIGraphicsBeginImageContext(bounds.size);
    74. CGContextRef context = UIGraphicsGetCurrentContext();
    75. if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
    76. CGContextScaleCTM(context, -scaleRatio, scaleRatio);
    77. CGContextTranslateCTM(context, -height, 0);
    78. }
    79. else {
    80. CGContextScaleCTM(context, scaleRatio, -scaleRatio);
    81. CGContextTranslateCTM(context, 0, -height);
    82. }
    83. CGContextConcatCTM(context, transform);
    84. CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
    85. UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    86. UIGraphicsEndImageContext();
    87. return imageCopy;
    88. }
时间: 2024-08-01 00:10:39

CGAffineTransformMake(a,b,c,d,tx,ty) 矩阵运算的原理的相关文章

第6月第17天 CGAffineTransformMake(a,b,c,d,tx,ty) 矩阵运算的原理

1. 为了把二维图形的变化统一在一个坐标系里,引入了齐次坐标的概念,即把一个图形用一个三维矩阵表示,其中第三列总是(0,0,1),用来作为坐标系的标准.所以所有的变化都由前两列完成. 以上参数在矩阵中的表示为: |a    b    0| |c    d    0| |tx   ty   1| 运算原理:原坐标设为(X,Y,1); |a    b    0| [X,Y,  1]      |c    d    0|     =     [aX + cY + tx   bX + dY + ty 

从UIImage的矩阵变换看矩阵运算的原理

1.矩阵的基本知识: struct CGAffineTransform {  CGFloat a, b, c, d;  CGFloat tx, ty;}; CGAffineTransform CGAffineTransformMake (CGFloat a,CGFloat b,CGFloat c,CGFloat d,CGFloat tx,CGFloat ty); 为了把二维图形的变化统一在一个坐标系里,引入了齐次坐标的概念,即把一个图形用一个三维矩阵表示,其中第三列总是(0,0,1),用来作为坐

oc知识点积累

1.iOS  project 和 target   http://blog.csdn.net/zhaozy55555/article/details/8557175 2.iOS 中的富文本文字设置      http://www.jianshu.com/p/8f49c9c99b21 3.iOS$299企业账号In House ipa发布流程   http://blog.sina.com.cn/s/blog_6cad9db90102uy0s.html 4.NSString&NSMutableStr

CGAffineTransformMake 矩阵变换 的运算原理

1.矩阵的基本知识: struct CGAffineTransform {  CGFloat a, b, c, d;  CGFloat tx, ty;}; CGAffineTransform CGAffineTransformMake (CGFloat a,CGFloat b,CGFloat c,CGFloat d,CGFloat tx,CGFloat ty); 为了把二维图形的变化统一在一个坐标系里,引入了齐次坐标的概念,即把一个图形用一个三维矩阵表示,其中第三列总是(0,0,1),用来作为坐

ios开发中的矩阵转换

最近在研究CoreText看了很多的例子其中有很多地方不是特别理解所以上网收集了IOS矩阵的转换原理来记录下 本文转载自:http://blog.csdn.net/lamp_zy/article/details/8474818 CGAffineTransformMake(a,b,c,d,tx,ty) ad缩放bc旋转tx,ty位移,基础的2D矩阵 公式 x=ax+cy+tx    y=bx+dy+ty 1.矩阵的基本知识: struct CGAffineTransform {  CGFloat

iOS核心面试题

1,请简述你对协议的理解?    protocol无论是在那个领域都是一种约束,规范.在OC中的协议主要用于在各个类之间进行回调传值. 协议有 委托方,代理方, 委托方是协议的制定者,需要声明协议的方法,实现协议的对象.代理方,是协议的遵守着,需要遵守协议,并实现协议中的必要方法. 2,如何理解ARC自动引用计数机制? Cocoa采用了引用计数(referencecounting)机制,每一个对象有一个关联的“整数retainCount”用于记录对象的使用情况.对象被引用时retaincount

Core Animation高级理论知识汇总

一. 基本概念 Core Animation其实是一个令人误解的命名.你可能认为它只是用来做动画的,但实际上它是从一个叫做Layer Kit这么一个不怎么和动画有关的名字演变而来,所以做动画这只是Core Animation特性的冰山一角.Core Animation是一个复合引擎,它的职责就是尽可能快地组合屏幕上不同的可视内容,这个内容是被分解成独立的图层,存储在一个叫做图层树的体系之中.于是这个树形成了UIKit以及在iOS应用程序当中你所能在屏幕上看见的一切的基础.和UIView最大的不同

UIView的动画之初步学习

animateWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> options:<#(UIViewAnimationOptions)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#> duration: 动画时长 delay: 决定了动画在延迟多久之后执行 options:

iOS下的2D仿射变换机制(CGAffineTransform相关)

仿射变换简介 仿射变换源于CoreGraphics框架,主要作用是绘制2D级别的图层,几乎所有iOS设备屏幕上的界面元素都是由CoreGraphics来负责绘制.而我们要了解的2D仿射变换是其下负责二维坐标到二维坐标的线性变换工作,它保持了二维图形的“平直性”(即:直线经过变换之后依然是直线,圆弧经过变换之后依然是圆弧)和“平行性”(即:二维图形之间的相对位置关系保持不变,平行线依然是平行线,且直线上点的位置顺序不变),只有依照向量产生的二维线条间的夹角会可能发生变化.仿射变换包括:平移(Tra