`
啸笑天
  • 浏览: 3469137 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

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

 

 

参考:

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

分享到:
评论
2 楼 vbtboy 2014-09-15  
     
1 楼 vbtboy 2014-09-15  

相关推荐

    CGAffineTransformMake(a,b,c,d,tx,ty) 矩阵运算的原理 - 不积跬步 无以至千里 不积小流 无

    CGAffineTransformMake(a,b,c,d,tx,ty) 矩阵运算的原理 矩阵运算是计算机图形学和图像处理中非常重要的一部分,CGAffineTransformMake(a,b,c,d,tx,ty) 函数是iOS开发中用于创建一个仿射变换矩阵的函数。本文将详细...

    TX1B单片机原理图

    通过阅读和分析【TX-1B型单片机开发板原理图.pdf】,开发者和工程师可以深入了解TX1B单片机的内部构造,掌握如何正确连接外部组件,以及如何编写高效代码来驱动硬件。这份文档对于学习、设计和调试基于TX1B的项目至...

    TX-1C原理图

    《TX-1C原理图详解:解构实验板分块设计》 TX-1C原理图是电子工程领域中一种重要的技术文档,它详细描述了TX-1C实验板的电路设计,为工程师们提供了清晰的电路布局和功能模块划分。在深入探讨TX-1C原理图之前,我们...

    C语言实现矩阵的乘法、平移、旋转和矩阵求逆

    A^-1 = (1/det(A)) * [d -b, -c a] ``` 其中det(A)是矩阵的行列式,对于2x2矩阵,det(A) = ad - bc。 在C语言中实现这些操作,你需要创建模板类(如果使用C++)或者函数来处理矩阵的实例。类可能包含初始化、...

    TX-1C 原理图

    从给定的文件信息来看,这是一份关于TX-1C实验板的电路原理图的详细解析,该实验板基于郭天祥的《新概念51单片机C语言教程》设计,旨在为学习者提供一个实践平台,深入了解51单片机的硬件结构与编程。下面将对这份...

    tx-1c电路原理图及pcb板

    《tx-1c电路原理图及PCB板详解》 在电子工程领域,设计和制作电路板是一项技术性极强的工作。本篇文章将围绕“tx-1c”电路原理图和PCB板展开,深入解析其中的技术细节和设计要点。这款电路板的设计者使用了业界知名...

    Jetson TX2底板原理图和PCB

    在本主题中,我们主要探讨的是Jetson TX2底板的原理图和PCB设计。 首先,原理图是电子设备设计的基础,它展示了所有组件之间的电气连接关系。对于Jetson TX2底板,原理图将揭示电源管理、内存接口、扩展接口(如...

    Jetson TX2原理图

    8. I2C端口与设备地址:原理图详细列出了I2C端口分配和从设备地址,包括INA3221(电源测量)、TCA9539(GPIO扩展器)、TMP451(温度传感器)、ADS1015(AC检测)和INA226(电源测量)等设备,这些信息对于系统初始化...

    TX-1C型单片机实验板原理图

    ### TX-1C型单片机实验板原理图解析 #### 概述 TX-1C型单片机实验板是郭天祥教授经典单片机教学系列中的一个实验平台,该实验板集成了多种功能模块,适用于学习单片机的基础操作及高级应用。本文将对TX-1C型单片机...

    TX51单片机原理图

    TX51单片机原理TX51单片机原理TX51单片机原理TX51单片机原理

    郭天祥 TX-1C型经典版单片机开发板原理图(高清完整版)

    由于提供的文件内容存在扫描识别错误,导致部分内容难以理解,但我将尽可能地基于提供的信息,对郭天祥TX-1C型单片机开发板的原理图进行知识点的梳理。本开发板原理图的知识点主要集中在单片机的内部组成、引脚功能...

    tx-1c原理图

    ### tx-1c原理图解析 #### 单片机最小系统的理解 在探索单片机的世界里,了解其最小系统是非常关键的一步。一个单片机最小系统通常包含单片机、电源供应、时钟电路以及必要的外围电路等基本组成部分。通过对tx-1c...

    TX-1B型单片机开发板原理图

    TX-1B型单片机开发板原理图 TX-1B型单片机开发板原理图 TX-1B型单片机开发板原理图

    764264765tx-1c 原理图.pdf

    在标题中,“***tx-1c 原理图.pdf”可能代表了一个特定的单片机原理图文件的名称,通常原理图是一个电子设备电路图的图形表示,它展示了电子组件之间的连接关系,包括所有的细节,如电阻、晶体管、二极管、电容、...

    郭天祥10天学会51单片机_TX-1C型单片机开发板原理图.zip

    在“TX-1C型单片机开发板原理图”中,我们可以看到开发板的具体硬件配置,包括: 1. **微处理器**:51系列的单片机,例如AT89S52或STC89C52。 2. **电源电路**:为开发板提供稳定的工作电压,通常包括直流电源输入...

    TX-1C型单片机实验板原理图_51单片机原理图_

    51单片机原理图 各个模块都包含在内 希望对大家有所帮助

    TX-1B型单片机开发板原理图.pdf

    从给定的文件信息“TX-1B型单片机开发板原理图”中,我们可以提炼出关于TX-1B单片机开发板的关键技术知识点,涵盖了硬件设计、电路组件、信号引脚功能以及外围设备的接口等多方面内容。 ### 1. 开发板核心:AT89S52...

    天祥电子51单片机开发板(TX-1C)proteus原理图

    有了这个天祥电子51单片机开发板(TX-1C)proteus原理图就能完全进行仿真了,省去买开发板.可以直接仿真。

    TX-1C PCB与原理图

    TX-1C的PCB与原理图,QQ:978120142

Global site tag (gtag.js) - Google Analytics