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

      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(0, 0, 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.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, 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(0, 0, width, height), imgRef);    
    164       
    165     UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();  
    166          
    167     UIGraphicsEndImageContext();    
    168          
    169     return imageCopy;    
    170       
    171 } 
    View Code

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

  • 相关阅读:
    JS trim的实现
    采用 LinQ 替代 SortedDictionary
    Int Cint Fix 函数的区别
    iptables详解(13):iptables动作总结之二
    iptables详解(12):iptables动作总结之一
    iptables详解(11):iptables之网络防火墙
    iptables详解(10):iptables自定义链
    iptables详解(9):iptables的黑白名单机制
    iptables详解(8):iptables扩展模块之state扩展
    iptables详解(7):iptables扩展之udp扩展与icmp扩展
  • 原文地址:https://www.cnblogs.com/sleepingSun/p/5139648.html
Copyright © 2011-2022 走看看