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 ...
随机推荐
- 在使用Fake framework的时候,为什么有一些函数没有生产mock呢?
在使用Visual studio 2012 的Fake framework 做单元测试的时候,你会发现有一些函数没有生产Stub 或者 Shim的版本,这可能是由于Fake的一些限制导致的,但如何知道 ...
- cocos2dx3.4 解析json文件
头文件: #include "json/document.h" #include "json/stringbuffer.h" #include "js ...
- CSS3学习之 animation 属性
发现animation这个新属性很有趣,在此学习,并整理下! 浏览器支持: Internet Explorer 10.Firefox 以及 Opera 支持 animation 属性: Safari ...
- mysql查询结果中文显示成了问号
在mysql的配置文件my.ini中的[mysqld]项中加这两句 character-set-server = utf8 collation-server = utf8_general_ci 在任务 ...
- C,C++,JAVA char,各占字节数
char在C和C+中占一个字节 Java中无论是汉字还是英文字母都是用Unicode编码来表示的,一个Unicode码是16位,每字节是8位,所以一个Unicode码占两字节 /** * The nu ...
- UVA 11736 Debugging RAM
模拟题: 比赛的时候忘记把1变成64位的1了,跪了好久: #include<cstdio> #include<cstring> #include<map> #inc ...
- hdu 3715
一个很简单的2-sat的题: 不过比较难想到: 其实也不是很难,可能接触的少了吧! #include<cstdio> #include<vector> #define maxn ...
- PHP7正式版测试,性能惊艳!
本周迎来2015年编程语言界的两件大事,Swift7 开源, PHP7 发布.这两件大事,都是可以载入相应的编程语言的史册级的事件. Swift 开源的事,咱先不说了,知乎上也有热烈的讨论,我们今天就 ...
- php的curl获取https加密协议请求返回json数据进行信息获取
<?php header("Content-type:text/html; charset=utf-8");function getToken($url){ $ ...
- UINavigationController使用的注意事项
1.常用属性viewControllers //所有在栈中的控制器topViewController //栈顶控制器navigationBar //导航栏 竖屏下默认44,横屏默认32 2.对navi ...