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的矩阵运算的例子,无外乎是运用以上三种变换的组合,达到所定义的效果
- //UIImageOrientation的定义,定义了如下几种变换
- typedef enum
- {
- UIImageOrientationUp, // default orientation
- UIImageOrientationDown, // 180 deg rotation
- UIImageOrientationLeft, // 90 deg CCW
- UIImageOrientationRight, // 90 deg CW
- UIImageOrientationUpMirrored, // as above but image mirrored along other axis. horizontal flip
- UIImageOrientationDownMirrored, // horizontal flip
- UIImageOrientationLeftMirrored, // vertical flip
- UIImageOrientationRightMirrored, // vertical flip
- } UIImageOrientation;
- //按照UIImageOrientation的定义,利用矩阵自定义实现对应的变换;
- -(UIImage *)transformImage:(UIImage *)aImage
- {
- CGImageRef imgRef = aImage.CGImage;
- CGFloat width = CGImageGetWidth(imgRef);
- CGFloat height = CGImageGetHeight(imgRef);
- CGAffineTransform transform = CGAffineTransformIdentity;
- CGRect bounds = CGRectMake(0, 0, width, height);
- CGFloat scaleRatio = 1;
- CGFloat boundHeight;
- UIImageOrientation orient = aImage.imageOrientation;
- switch(UIImageOrientationLeftMirrored)
- {
- case UIImageOrientationUp:
- transform = CGAffineTransformIdentity;
- break;
- case UIImageOrientationUpMirrored:
- transform = CGAffineTransformMakeTranslation(width, 0.0);
- transform = CGAffineTransformScale(transform, -1.0, 1.0); //沿y轴向左翻
- break;
- case UIImageOrientationDown:
- transform = CGAffineTransformMakeTranslation(width, height);
- transform = CGAffineTransformRotate(transform, M_PI);
- break;
- case UIImageOrientationDownMirrored:
- transform = CGAffineTransformMakeTranslation(0.0, height);
- transform = CGAffineTransformScale(transform, 1.0, -1.0);
- break;
- case UIImageOrientationLeft:
- boundHeight = bounds.size.height;
- bounds.size.height = bounds.size.width;
- bounds.size.width = boundHeight;
- transform = CGAffineTransformMakeTranslation(0.0, width);
- transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
- break;
- case UIImageOrientationLeftMirrored:
- boundHeight = bounds.size.height;
- bounds.size.height = bounds.size.width;
- bounds.size.width = boundHeight;
- transform = CGAffineTransformMakeTranslation(height, width);
- transform = CGAffineTransformScale(transform, -1.0, 1.0);
- transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
- break;
- case UIImageOrientationRight: //EXIF = 8
- boundHeight = bounds.size.height;
- bounds.size.height = bounds.size.width;
- bounds.size.width = boundHeight;
- transform = CGAffineTransformMakeTranslation(height, 0.0);
- transform = CGAffineTransformRotate(transform, M_PI / 2.0);
- break;
- case UIImageOrientationRightMirrored:
- boundHeight = bounds.size.height;
- bounds.size.height = bounds.size.width;
- bounds.size.width = boundHeight;
- transform = CGAffineTransformMakeScale(-1.0, 1.0);
- transform = CGAffineTransformRotate(transform, M_PI / 2.0);
- break;
- default:
- [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
- }
- UIGraphicsBeginImageContext(bounds.size);
- CGContextRef context = UIGraphicsGetCurrentContext();
- if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
- CGContextScaleCTM(context, -scaleRatio, scaleRatio);
- CGContextTranslateCTM(context, -height, 0);
- }
- else {
- CGContextScaleCTM(context, scaleRatio, -scaleRatio);
- CGContextTranslateCTM(context, 0, -height);
- }
- CGContextConcatCTM(context, transform);
- CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
- UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return imageCopy;
- }
CGAffineTransformMake(a,b,c,d,tx,ty) 矩阵运算的原理的更多相关文章
- 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.矩阵的基 ...
- 第6月第17天 CGAffineTransformMake(a,b,c,d,tx,ty) 矩阵运算的原理
1. 为了把二维图形的变化统一在一个坐标系里,引入了齐次坐标的概念,即把一个图形用一个三维矩阵表示,其中第三列总是(0,0,1),用来作为坐标系的标准.所以所有的变化都由前两列完成. 以上参数在矩阵中 ...
- 从UIImage的矩阵变换看矩阵运算的原理
1.矩阵的基本知识: struct CGAffineTransform { CGFloat a, b, c, d; CGFloat tx, ty;}; CGAffineTransform CGAf ...
- CGAffineTransformMake 矩阵变换 的运算原理(转)
1.矩阵的基本知识: struct CGAffineTransform { CGFloat a, b, c, d; CGFloat tx, ty; }; CGAffineTransform CGAff ...
- IOS-CGAffineTransformMake 矩阵变换 的运算原理
1.矩阵的基本知识: struct CGAffineTransform { CGFloat a, b, c, d; CGFloat tx, ty; }; CGAffineTransform C ...
- transform初学习
1.什么是transform? transform主要用于形变,位移和旋转,可用于动画. p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: jus ...
- iOS:动画(18-10-15更)
目录 1.UIView Animation 1-1.UIView Animation(基本使用) 1-2.UIView Animation(转场动画) 2.CATransaction(Layer版的U ...
- 关于opengl中的矩阵平移,矩阵旋转,推导过程理解 OpenGL计算机图形学的一些必要矩阵运算知识
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/12166896.html 为什么引入齐次坐标的变换矩阵可以表示平移呢? - Yu Mao的回答 ...
- UIView的动画之初步学习
animateWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> options:<#(UIView ...
随机推荐
- 安装使用adobe_photoshop_cs6
1.先断开网络,安装官方原版PS程序. 2.在安装程序界面选择“试用”安装. 3.等安装完成后,退出程序. 4.复制破解补丁到安装路径覆盖,如:D:\Program Files\Adobe\Adobe ...
- 常用javascript代码片段集锦
常用方法的封装 根据类名获取DOM元素 var $$ = function (className, element) { if (document.getElementsByClassName) { ...
- python 下载安装及setuptools应用
1.首先下载python安装程序,下载地址:https://www.python.org/download/releases/2.7.8/ 如下图: 因为我的机器是32位的就选择了Windows x8 ...
- Python的字符串操作和Unicode
字符串类型 str:Unicode字符串.采用''或者r''构造的字符串均为str,单引号可以用双引号或者三引号来代替.无论用哪种方式进行制定,在Python内部存储时没有区别. bytes:二进制字 ...
- Spring 数据源配置一:单一数据源
最近遇到一个项目,需要访问都多个数据源,并且数据库是不同厂商(mysql, sqlserver). 所以对此做了一些研究,这里咱们采用渐进的方式来展开,先谈谈单一数据源配置.(稍后有时间会陆续补充其 ...
- oracle dblink 配置两个ip
create database link test_link connect to xx identified by xx using '(DESCRIPTION = (ADDRESS_LIST = ...
- JavaScript闭包底层解析
1. 闭包是一个函数,这个函数有权访问另一个函数作用域中的变量,创建闭包最常见的方式,就是在函数内部创建函数.要想彻底搞清其中细节,必须从函数从创建到调用的时候都发生了什么入手 2. 函数第一次被调用 ...
- Spring中的一个错误:使用Resources时报错(The annotation @Resources is disallowed for this location)
在学习Spring的过程中遇到一个错误:在使用注解@resources的时候提示:The annotation @Resources is disallowed for this location 后 ...
- matlab怎么同时显示imshow 两幅图片
matlab怎么同时显示imshow 两幅图片 matlab怎么同时显示imshow 两幅图片 方法一:subplot()函数 subplot(2,1,1); subplot(2,1,2); 分上下或 ...
- *[topcoder]TheTree
http://community.topcoder.com/stat?c=problem_statement&pm=12746&rd=15703 这道题有意思.给了树的根和每层节点的个 ...