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

偶然间看到一片讲解 矩阵动画解释听简洁的帖子,收藏下。顺便说下,其实官方开发文档中对于很多知识点有详细的介绍,大家平时可以多阅读文档。。。(虽然是英文的)

原文地址:http://justsee.iteye.com/blog/1969933


--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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.   
  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(00, width, height);    
  37.          
  38.     CGFloat scaleRatio = 1;    
  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.01.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.01.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.01.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, 0);    
  150.           
  151.     }    
  152.       
  153.     else {    
  154.           
  155.         CGContextScaleCTM(context, scaleRatio, -scaleRatio);    
  156.           
  157.         CGContextTranslateCTM(context, 0, -height);    
  158.           
  159.     }    
  160.          
  161.     CGContextConcatCTM(context, transform);    
  162.          
  163.     CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(00, 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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
求解仿射变换矩阵的原理是通过已知的变换前后的点坐标关系,推导出变换矩阵的系数。 具体步骤如下: 1. 假设已知变换前后的点坐标关系,可以列出如下方程组: x' = a11*x + a12*y + tx y' = a21*x + a22*y + ty 其中,(x,y)为原始点的坐标,(x',y')为变换后点的坐标,a11、a12、a21、a22为矩阵系数,txty为平移量。 2. 将方程组用矩阵表示: | x' | | a11 a12 tx | | x | | | = | | * | | | y' | | a21 a22 ty | | y | 3. 为了求解矩阵系数,需要用到矩阵的求逆运算。由于仿射变换矩阵是二维矩阵,因此可以使用公式求解矩阵的逆: A^-1 = 1/ det(A) * adj(A) 其中,det(A)为矩阵A的行列式,adj(A)为矩阵A的伴随矩阵。 4. 将方程组的矩阵形式和逆矩阵代入公式,得到矩阵系数: | a11 a12 tx | | x | | x' | | | * | | = | | | a21 a22 ty | | y | | y' | a11 = (x1' - x3')*(y2 - y3') - (x2' - x3')*(y1 - y3') a12 = (x2' - x3')*(x1 - x3') - (x1' - x3')*(x2 - x3') a21 = (y2' - y3')*(y1 - y3') - (y1' - y3')*(y2 - y3') a22 = (y1' - y3')*(x2 - x3') - (y2' - y3')*(x1 - x3') tx = x1' - a11*x1 - a12*y1 ty = y1' - a21*x1 - a22*y1 其中,(x1,y1)、(x2,y2)、(x3,y3)为变换前的三个点坐标,(x1',y1')、(x2',y2')、(x3',y3')为变换后的三个点坐标。 5. 求解出矩阵系数和平移量后,将其组合成仿射变换矩阵即可。 总结起来,求解仿射变换矩阵的过程就是通过解方程组和矩阵运算,推导出变换矩阵的系数和平移量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值