第一次写ios相关技术博客,所以先写个简单的,写的不好大家多多提意见。
想学好这个类,我感觉最好还是从理论上弄明白什么二维图形到底是怎么变换的。
矩阵及其运算
一.数学概念
定义1.1 由!
![](https://img.haomeiwen.com/i1682758/4ce4bdcd4dcde8a1.gif)
个数
![](https://img.haomeiwen.com/i1682758/bf2b0e689ce5fad2.gif)
排成m行n列的数表
![](https://img.haomeiwen.com/i1682758/b71cb5bfd73b0127.gif)
称为m行n列的矩阵,简称 矩阵,记作
![](https://img.haomeiwen.com/i1682758/301e0a68fdb37311.gif)
二.原理,公式和法则
1.矩阵的加法
(1) 公式
![](https://img.haomeiwen.com/i1682758/d56b80d8af6e253f.gif)
(2) 运算律
![](https://img.haomeiwen.com/i1682758/705ee35bfaf3f760.gif)
2.数乘矩阵
(1) 公式
![](https://img.haomeiwen.com/i1682758/fc629cbbfc773639.gif)
(2) 运算律
![](https://img.haomeiwen.com/i1682758/3182f8639d762658.gif)
3.矩阵与矩阵相乘
![](https://img.haomeiwen.com/i1682758/f0496654ba14dbde.gif)
, 则
![](https://img.haomeiwen.com/i1682758/044fb12702229319.gif)
,其中
![](https://img.haomeiwen.com/i1682758/50dc28641f3c4315.gif)
,且
![](https://img.haomeiwen.com/i1682758/9ef0c336d60cd48b.gif)
(2) 运算符(假设运算都是可行的):
![](https://img.haomeiwen.com/i1682758/24731f87fe459c40.gif)
(3) 方阵的运算
![](https://img.haomeiwen.com/i1682758/5cceb8f5b7d2f587.gif)
注意:①矩阵乘法一般不满足交换律。
![](https://img.haomeiwen.com/i1682758/f09eeb17704b5dbd.gif)
4.矩阵的转置
(1) 公式
![](https://img.haomeiwen.com/i1682758/07a5df6933dec3e1.png)
![](https://img.haomeiwen.com/i1682758/e9807f2ae1374c51.png)
(2) 运算律
![](https://img.haomeiwen.com/i1682758/fdb2bd9ebb8db081.gif)
!
5.方阵的行列式
![](https://img.haomeiwen.com/i1682758/c0c477f0653bd57d.png)
6.共轭矩阵
![](https://img.haomeiwen.com/i1682758/dc5d1654bde7de02.png)
上面一定要看懂矩阵的乘法是怎么运算的才行。
数学原理
1、基本几何变换及变换矩阵
基本几何变换都是相对于坐标原点和坐标轴进行的几何变换,有平移、比例、旋转、反射和错切等
1.1 平移变换
是指将p点沿直线路径从一个坐标位置移到另一个坐标位置的重定位过程。他是一种不产生变形而移动物体的刚体变换(rigid-body transformation),如下图所示。
![](https://img.haomeiwen.com/i1682758/029f86d44cf2764a.png)
推导:
![](https://img.haomeiwen.com/i1682758/664a9cb47ab7a118.png)
解释(个人理解)
x'=x+Tx 相当于x'= x*1 + y*0 + 1 * Tx
y'=y+Ty 相当于y'= x*0 + y*1 + 1 * Ty
所以 A 矩阵 [x y 1]
C 矩阵要和A矩阵格式一样 [x' y' 1]
c矩阵的1 怎么来。只能添加一行了
1=x*0+y*0+ 1*1
所以b矩阵为 上面如图
1.2 缩放变换
缩放变换是指对p点相对于坐标原点沿x方向放缩Sx倍,沿y方向放缩Sy倍。其中Sx和Sy称为缩放系数。
![](https://img.haomeiwen.com/i1682758/302e3513ea237ae9.png)
推导:
![](https://img.haomeiwen.com/i1682758/f8742a956260b04d.png)
矩阵
![](https://img.haomeiwen.com/i1682758/ba3cb0f58fa32996.png)
x'=x*Sx+y*0 + 0*0;
y'=x*0 +y *Sy+0*0;
0=x*0+y*0+0*1;
缩放变换可改变物体的大小,如下图所示。当Sx=Sy >1时,图形沿两个坐标轴方向等比例放大;当Sx=Sy<1,图形沿两个坐标轴方向等比例缩小;当Sx≠Sy,图形沿两个坐标轴方向作非均匀的比例变换。
![](https://img.haomeiwen.com/i1682758/3764c4e002bcfbc2.png)
1.3 旋转变换
二维旋转是指将p点绕坐标原点转动某个角度(逆时针为正,顺时针为负)得到新的点p’的重定位过程。
[图片上传失败...(image-cbfe81-1535962641767)]
推导:利用极坐标方程
![](https://img.haomeiwen.com/i1682758/f16527d3b1559cc8.png)
逆时针旋转θ角的矩阵如下:
![](https://img.haomeiwen.com/i1682758/33101ca7b96c9c40.png)
1.4 对称变换
对称变换后的图形是原图形关于某一轴线或原点的镜像。
![](https://img.haomeiwen.com/i1682758/cb75d4a8f65ecace.png)
(1)关于x轴对称
![](https://img.haomeiwen.com/i1682758/a3468984d5c0f219.png)
x'=x*1+y*0+0*0;
y'=x*0+y*(-1)+0*0;
0=x*0+y*0+0*1;
(2)关于y轴对称
![](https://img.haomeiwen.com/i1682758/133d9e7c60fd4c02.png)
(3)关于原点对称
![](https://img.haomeiwen.com/i1682758/577da1b55fcf0193.png)
(4)关于y=x轴对称
![](https://img.haomeiwen.com/i1682758/73a82b3321e50df1.png)
(5)关于y=-x轴对称
![](https://img.haomeiwen.com/i1682758/699be35b7768bdca.png)
1.5 错切变换
错切变换也称为剪切、错位变换,用于产生弹性物体的变形处理。
![](https://img.haomeiwen.com/i1682758/56d05b0d0ee07aa6.png)
错切变换的变换矩阵为:
![](https://img.haomeiwen.com/i1682758/250e56acab710df1.png)
(1)沿x方向错切:b=0
(2)沿y方向错切:c=0
(3)两个方向错切:b和c都不等于0。
2、 复合变换
如果图形要做一次以上的几何变换,那么可以将各个变换矩阵综合起来进行一步到位的变换。复合变换有如下的性质:
1)复合平移
对同一图形做两次平移相当于将两次的平移两加起来:
![](https://img.haomeiwen.com/i1682758/84304505d33ff0c6.png)
2)复合缩放
两次连续的缩放相当于将缩放操作相乘:
![](https://img.haomeiwen.com/i1682758/8964f1cdd7a75e1e.png)
3)复合旋转
两次连续的旋转相当于将两次的旋转角度相加:
![](https://img.haomeiwen.com/i1682758/727c5bea2df9904b.png)
缩放、旋转变换都与参考点有关,上面进行的各种变换都是以原点为参考点的。如果相对某个一般的参考点(xf,yf)作缩放、旋转变换,相当于将该点移到坐标原点处,然后进行缩放、旋转变换,最后将(xf,yf)点移回原来的位置。
4)关于(xf,yf)点的缩放变换
![](https://img.haomeiwen.com/i1682758/683d197d885b7ebb.png)
5)绕(xf,yf)点的旋转变换
![](https://img.haomeiwen.com/i1682758/787c391cefca7d97.png)
3、二维图形几何变换的计算
几何变换均可表示成P’=P*T的形式
(1)点的变换:先将点表示为规范化齐次坐标形式,再乘以变换矩阵。
![](https://img.haomeiwen.com/i1682758/404161f701665d71.png)
(2)直线的变换:将直线的两个端点表示为规范化齐次坐标形式,再乘以变换矩阵。
![](https://img.haomeiwen.com/i1682758/2e0d4948b791cc1a.png)
(3)多边形的变换:将多边形的顶点表示为规范化齐次坐标形式,再乘以变换矩阵。
![](https://img.haomeiwen.com/i1682758/39e39d10ce396107.png)
(4)曲线的变换:将曲线的每个点表示为规范化齐次坐标形式,再乘以变换矩阵。
4、复合变换的矩阵点乘的先后问题
1)如果采用以下方式计算几何变换的变换矩阵
![](https://img.haomeiwen.com/i1682758/f73951cfdd676fcc.png)
如上范例所示,其先执行变换的矩阵放在前面,后执行变换的矩阵放在后面。
2)如果采用以下方式计算几何变换的变换矩阵:
![](https://img.haomeiwen.com/i1682758/6e185a705e1e31a3.png)
如上范例所示,其先执行变换的矩阵放在后面,后执行变换的矩阵放在前面。
这是因为矩阵的特性:![](https://img.haomeiwen.com/i1682758/94ab7f7d227c8d30.png)
CGAffineTransform.h 函数介绍
说了半天,不来点代码怎么行。
在CGAffineTransform.h 文件中
typedef struct CGAffineTransform CGAffineTransform;
struct CGAffineTransform {
CGFloat a, b, c, d;
CGFloat tx, ty;
};
矩阵数学模型是[a b]
c d
tx ty
省略了 [a b 0] 中的最后一列
c d 0
tx ty 1
函数介绍代码
///获取一个标准矩阵。没有变化的矩阵
CGAffineTransform transform= CGAffineTransformIdentity;
NSLog(@"CGAffineTransformIdentity 数值%@" , NSStringFromCGAffineTransform(transform));
///获取一个变幻矩阵 这个函数可以平移旋转和缩放
/* Return the transform [ a b c d tx ty ]. */
transform= CGAffineTransformMake(a, b, c, d,x,y);
///获取一个只做平移的矩阵
// t' = [ 1 0 0 1 tx ty ]
transform= CGAffineTransformMakeTranslation(x, y);
///获取一个缩放矩阵
// t' = [ sx 0 0 sy 0 0 ]
transform= CGAffineTransformMakeScale(a,c);
//获取一个旋转矩阵
/* Return a transform which rotates by `angle' radians:
t' = [ cos(angle) sin(angle) -sin(angle) cos(angle) 0 0 ] */
transform= CGAffineTransformMakeRotation(3);
///验证是否是标准矩阵
BOOL isTrue = CGAffineTransformIsIdentity(transform);
///这个是矩阵之间的换算了
/* Translate `t' by `(tx, ty)' and return the result:
t' = [ 1 0 0 1 tx ty ] * t */
/// 说的很明确 用只有平移的矩阵和 t 矩阵相乘 t*t' 意思是在t'的基础上做t 变幻(例如平移旋转等等)
transform= CGAffineTransformTranslate(transform,x,y);
///矩阵先缩放再transform
/* Scale `t' by `(sx, sy)' and return the result:
t' = [ sx 0 0 sy 0 0 ] * t */
transform= CGAffineTransformScale(transform,a,c);
///矩阵先旋转再transform
/* Rotate `t' by `angle' radians and return the result:
t' = [ cos(angle) sin(angle) -sin(angle) cos(angle) 0 0 ] * t */
transform = CGAffineTransformRotate(transform,3);
NSLog(@"CGAffineTransformInvert前 数值%@" , NSStringFromCGAffineTransform(transform));
/// 获取 反转矩阵 看不出效果。做图看看 可以仔细研究下
///我看着就是沿着y轴做了一个对称变换 (不见得对)
transform = CGAffineTransformInvert(transform);
NSLog(@"CGAffineTransformInvert后 数值%@" , NSStringFromCGAffineTransform(transform));
///矩阵相乘
/* Concatenate `t2' to `t1' and return the result:
t' = t1 * t2 */
transform = CGAffineTransformConcat(transform,transform);
///判断两个矩阵是否相等
/* Return true if `t1' and `t2' are equal, false otherwise. */
isTrue =CGAffineTransformEqualToTransform(transform,transform);
///获取一个点矩阵变幻另一个点的位置
/* Transform `point' by `t' and return the result:
p' = p * t
where p = [ x y 1 ]. */
CGPoint point= CGPointApplyAffineTransform(CGPointMake(30, 30), transform);
///获取一个矩形矩形变换的大小
/* Transform `size' by `t' and return the result:
s' = s * t
where s = [ width height 0 ]. */
CGSize size= CGSizeApplyAffineTransform(CGSizeMake(30, 30),transform);
///获取矩形位置变幻后的位置
CGRect rect=CGRectApplyAffineTransform(CGRectMake(0, 0, 30, 30),transform);
项目中有每个函数的具体用法。
![](https://img.haomeiwen.com/i1682758/ada157fa731ee600.gif)
项目托管在github
网友评论