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 +txbX + dY +ty1] ;

|tx    ty1|

通过矩阵运算后的坐标[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的定义,定义了如下几种变换

-(UIImage *)transformMake:(UIImage *)aImage{

//按照UIImageOrientation的定义,利用矩阵自定义实现对应的变换;

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) 矩阵运算的原理)