简记:

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. 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. }

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. CGAffineTransformMake 矩阵变换 的运算原理(转)

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

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

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

  6. transform初学习

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

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

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

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

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

  9. UIView的动画之初步学习

    animateWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> options:<#(UIView ...

随机推荐

  1. WPF的ScrollViewer鼠标的滚动

    在C# 中,两个ScrollViewer嵌套在一起或者ScrollViewer里面嵌套一个ListBox.Listview(控件本身有scrollviewer)的时候,我们本想要的效果是鼠标滚动整个S ...

  2. Excel导出-Epplus

    首先引入EPPlus.dll到你的项目bin文件中. Epplus引用的命名空间为 OfficeOpenXml 下面是对epplus一些用法的总结 一.创建一个空excel表格 //导出EXCEL设置 ...

  3. Java 内存区域

    Java虚拟机锁管理的内存包括以下几个运行时数据区域: 1.程序计数器: 程序计数器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里,字节码解释器工作时 ...

  4. HBase性能优化方法总结(转)

    本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法.有关HBase系统配置级别的优化,这里涉及的不多,这部分可以参考:淘宝Ken Wu同学的博客. 1. 表的设计 1.1 Pr ...

  5. hadoop 补充(转)

    1.输入文件: 文件是MapReduce任务的数据的初始存储地.正常情况下,输入文件一般是存在HDFS里.这些文件的格式可以是任意的:我们可以使用基于行的日志文件,也可以使用二进制格式,多行输入记录或 ...

  6. java转义字符(转载)

    转载自:http://blog.163.com/dingyi_57@126/blog/static/110479195200911229337281/ 一.为什么要使用转义字符? 1.  HTML中& ...

  7. 【web安全】第六弹:手工SQL注入详解

    前一段时间,在对SQL注入有了新的理解之后,写了这篇文章.本来准备投稿,因为内容过于基础被打回来了,想想屯着也没意思,发出来发出来~~本来有好多图的,但是博客园发图很麻烦,word文档的链接会贴在文章 ...

  8. C# - 接口,继承

    接口 接口是把公共实例(非静态)方法和属性组合起来,以封装特定功能的一个集合.不能像实例化一个类那样实例化接口.接口不能包含实现其成员的任何代码,而只能定义成员本身.实现过程必须在实现接口的类中完成. ...

  9. Ajax简单实现文件异步上传的多种方法

    1. 认识FormData对象 FormData是Html5新加进来的一个类,可以模拟表单数据 构造函数 FormData (optional HTMLFormElement form) (可选) 解 ...

  10. Linux PS 命令详解

    Linux操作系统PS命令详细解析 要对系统中进程进行监测控制,用 ps 命令满足你. /bin/ps ps 是显示瞬间行程的状态,并不动态连续:如果想对进程运行时间监控,应该用 top 工具. ki ...