简记:

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的矩阵运算的例子,无外乎是运用以上三种变换的组合,达到所定义的效果

  1. //UIImageOrientation的定义,定义了如下几种变换
  2. typedef enum
  3. {
  4. UIImageOrientationUp, // default orientation
  5.  
  6. UIImageOrientationDown, // 180 deg rotation
  7.  
  8. UIImageOrientationLeft, // 90 deg CCW
  9.  
  10. UIImageOrientationRight, // 90 deg CW
  11.  
  12. UIImageOrientationUpMirrored, // as above but image mirrored along other axis. horizontal flip
  13.  
  14. UIImageOrientationDownMirrored, // horizontal flip
  15.  
  16. UIImageOrientationLeftMirrored, // vertical flip
  17.  
  18. UIImageOrientationRightMirrored, // vertical flip
  19.  
  20. } UIImageOrientation;
  21.  
  22. //按照UIImageOrientation的定义,利用矩阵自定义实现对应的变换;
  23.  
  24. -(UIImage *)transformImage:(UIImage *)aImage
  25.  
  26. {
  27.  
  28. CGImageRef imgRef = aImage.CGImage;
  29.  
  30. CGFloat width = CGImageGetWidth(imgRef);
  31.  
  32. CGFloat height = CGImageGetHeight(imgRef);
  33.  
  34. CGAffineTransform transform = CGAffineTransformIdentity;
  35.  
  36. CGRect bounds = CGRectMake(, , width, height);
  37.  
  38. CGFloat scaleRatio = ;
  39.  
  40. CGFloat boundHeight;
  41.  
  42. UIImageOrientation orient = aImage.imageOrientation;
  43.  
  44. switch(UIImageOrientationLeftMirrored)
  45.  
  46. {
  47.  
  48. case UIImageOrientationUp:
  49.  
  50. transform = CGAffineTransformIdentity;
  51.  
  52. break;
  53.  
  54. case UIImageOrientationUpMirrored:
  55.  
  56. transform = CGAffineTransformMakeTranslation(width, 0.0);
  57.  
  58. transform = CGAffineTransformScale(transform, -1.0, 1.0); //沿y轴向左翻
  59.  
  60. break;
  61.  
  62. case UIImageOrientationDown:
  63. transform = CGAffineTransformMakeTranslation(width, height);
  64.  
  65. transform = CGAffineTransformRotate(transform, M_PI);
  66.  
  67. break;
  68.  
  69. case UIImageOrientationDownMirrored:
  70.  
  71. transform = CGAffineTransformMakeTranslation(0.0, height);
  72.  
  73. transform = CGAffineTransformScale(transform, 1.0, -1.0);
  74.  
  75. break;
  76.  
  77. case UIImageOrientationLeft:
  78.  
  79. boundHeight = bounds.size.height;
  80.  
  81. bounds.size.height = bounds.size.width;
  82.  
  83. bounds.size.width = boundHeight;
  84.  
  85. transform = CGAffineTransformMakeTranslation(0.0, width);
  86.  
  87. transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
  88.  
  89. break;
  90.  
  91. case UIImageOrientationLeftMirrored:
  92.  
  93. boundHeight = bounds.size.height;
  94.  
  95. bounds.size.height = bounds.size.width;
  96.  
  97. bounds.size.width = boundHeight;
  98.  
  99. transform = CGAffineTransformMakeTranslation(height, width);
  100.  
  101. transform = CGAffineTransformScale(transform, -1.0, 1.0);
  102.  
  103. transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
  104.  
  105. break;
  106.  
  107. case UIImageOrientationRight: //EXIF = 8
  108.  
  109. boundHeight = bounds.size.height;
  110.  
  111. bounds.size.height = bounds.size.width;
  112.  
  113. bounds.size.width = boundHeight;
  114.  
  115. transform = CGAffineTransformMakeTranslation(height, 0.0);
  116.  
  117. transform = CGAffineTransformRotate(transform, M_PI / 2.0);
  118.  
  119. break;
  120.  
  121. case UIImageOrientationRightMirrored:
  122.  
  123. boundHeight = bounds.size.height;
  124.  
  125. bounds.size.height = bounds.size.width;
  126.  
  127. bounds.size.width = boundHeight;
  128.  
  129. transform = CGAffineTransformMakeScale(-1.0, 1.0);
  130.  
  131. transform = CGAffineTransformRotate(transform, M_PI / 2.0);
  132.  
  133. break;
  134.  
  135. default:
  136.  
  137. [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
  138.  
  139. }
  140.  
  141. UIGraphicsBeginImageContext(bounds.size);
  142.  
  143. CGContextRef context = UIGraphicsGetCurrentContext();
  144.  
  145. if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
  146.  
  147. CGContextScaleCTM(context, -scaleRatio, scaleRatio);
  148.  
  149. CGContextTranslateCTM(context, -height, );
  150.  
  151. }
  152.  
  153. else {
  154.  
  155. CGContextScaleCTM(context, scaleRatio, -scaleRatio);
  156.  
  157. CGContextTranslateCTM(context, , -height);
  158.  
  159. }
  160.  
  161. CGContextConcatCTM(context, transform);
  162.  
  163. CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(, , width, height), imgRef);
  164.  
  165. UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
  166.  
  167. UIGraphicsEndImageContext();
  168.  
  169. return imageCopy;
  170.  
  171. }

借鉴: https://developer.apple.com/library/ios/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_affine/dq_affine.html

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

  1. 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.矩阵的基本 ...

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

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

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

    1.矩阵的基本知识: struct CGAffineTransform {  CGFloat a, b, c, d;  CGFloat tx, ty;}; CGAffineTransform CGAf ...

  4. 【spring】 <tx:annotation-driven /> 的理解 【转载的】

    在使用SpringMvc的时候,配置文件中我们经常看到 annotation-driven 这样的注解,其含义就是支持注解,一般根据前缀 tx.mvc 等也能很直白的理解出来分别的作用.<tx: ...

  5. CGAffineTransformMake 矩阵变换 的运算原理(转)

    1.矩阵的基本知识: struct CGAffineTransform { CGFloat a, b, c, d; CGFloat tx, ty; }; CGAffineTransform CGAff ...

  6. IOS-CGAffineTransformMake 矩阵变换 的运算原理

    1.矩阵的基本知识: struct CGAffineTransform {   CGFloat a, b, c, d;   CGFloat tx, ty; }; CGAffineTransform C ...

  7. transform初学习

    1.什么是transform? transform主要用于形变,位移和旋转,可用于动画. p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: jus ...

  8. iOS:动画(18-10-15更)

    目录 1.UIView Animation 1-1.UIView Animation(基本使用) 1-2.UIView Animation(转场动画) 2.CATransaction(Layer版的U ...

  9. 关于opengl中的矩阵平移,矩阵旋转,推导过程理解 OpenGL计算机图形学的一些必要矩阵运算知识

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/12166896.html 为什么引入齐次坐标的变换矩阵可以表示平移呢? - Yu Mao的回答 ...

随机推荐

  1. iOS伪实现打地鼠游戏

    打地鼠是一款可以用iOS知识来实现的一种游戏.其核心技术就是通过imageView来播放动画,点击button时来停止当前播放的动画开始击打地鼠的动画.话不多说直接上代码. 这是添加当前的背景图片,然 ...

  2. 一个简单的flask程序

    初始化 所有Flask程序都必须创建一个程序实例. 程序实例是Flask类的对象,经常使用下述代码创建: from flask import Flask app = Flask(__name__) F ...

  3. 《Effective C++ 》学习笔记——条款03

    ***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...

  4. 《JavaScript 闯关记》之简介

    简介 JavaScript 是面向 Web 的编程语言,绝大多数现代网站都使用了 JavaScript,并且所有的现代 Web 浏览器(电脑,手机,平板)均包含了 JavaScript 解释器. 这使 ...

  5. css渐变/背景

    1.线性渐变(gradient变化) linear-gradient线性渐变指沿着某条直线朝一个方向产生渐变效果. 上图是从黄色渐变到绿色 background:linear-gradient( to ...

  6. UVA 10570 Meeting with Aliens

    题意: N个外星人围成一桌坐下,有序的排列指N在N-1与N+1中间,现在给出一个序列,问至少交换几次可以得到有序的序列. 分析: 复制一遍输入序列,放在原序列之后.相当于环.通过枚举,可以把最小交换次 ...

  7. C++ Primer 读书笔记:第11章 泛型算法

    第11章 泛型算法 1.概述 泛型算法依赖于迭代器,而不是依赖容器,需要指定作用的区间,即[开始,结束),表示的区间,如上所示 此外还需要元素是可比的,如果元素本身是不可比的,那么可以自己定义比较函数 ...

  8. DBI && MySQL lock

    DBI: url set isolation to dirty read my $npmdb_dbh = DBI->connect("DBI:ODBC:npmdb", &qu ...

  9. [Python] 应用kNN算法预测豆瓣电影用户的性别

    应用kNN算法预测豆瓣电影用户的性别 摘要 本文认为不同性别的人偏好的电影类型会有所不同,因此进行了此实验.利用较为活跃的274位豆瓣用户最近观看的100部电影,对其类型进行统计,以得到的37种电影类 ...

  10. POJ 1052 Plato's Blocks

      Plato's Blocks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 734   Accepted: 296 De ...