2d仿射变换及单点多点触摸

iphone 中2d的仿射变换共有3种形式:

1.Translate 位移

对应方法有:

CGAffineTransform CGAffineTransformTranslate(CGAffineTransform t,  CGFloat tx, CGFloat ty);

CGAffineTransform CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty);

注:t 代表相对变换,tx,ty 代表相对位移

2.Scale 缩放

对应方法有:

CGAffineTransform CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy);

CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy);

注:t代表相对变换,sx,sy代表缩放倍数

3.Rotate 旋转

对应方法有:

CGAffineTransform CGAffineTransformRotate(CGAffineTransform t, CGFloat angle);

CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle);

注:t代表相对变换,angle代表相对弧度(角度)

 

2d仿射变换是相对于UIView来说的,在UIView.CALayer中则会使用到3d的仿射变换,用来实现3d的效果。

 

UIView 中,默认的反射变换值是:

const CGAffineTransform CGAffineTransformIdentity;

当调用如下语句是,UIView 会还原到初始状态

UIView.transform = CGAffineTransformIdentity

 

一般来说,做第一次仿射变换时,都是相对于UIView当前的状态,那么第一次创建的时候应该:

CGAffineTransform transform = CGAffineTransformTranslate(self.transform,tx,ty);

 

在根据触摸来控制仿射变换时,比如图片的移动,旋转,缩放等时,需要判断手势的移动。

这里所有的点均表示相对触发触摸的UIView的位置 即 Point currentPoint = [touch locationInView:touch.view];

 

1.位移

位移的主要思路是移动后的目标点到起始点的偏移量,这里需要两个信息,起始点和当前点

起始点startPoint,当前点currentPoint

那么偏移量 CGPoint offset = CGPointMake(currentPoint.x – startPoint.x,currentPoint.y – startPoint.y);

于是可以调用 CGAffineTransformMakeTranslation(offset.x,offset.y);

 

1)单点触摸时

startPoint 是在touchBegan中唯一touch的坐标点

currentPoint 是在touchMoved中唯一touch的坐标点

2)多点触摸时

多点触摸时,一般用2个点来定位,我们需要记录4个点,并且,需要确认2个touch,因为在触摸过程中,touch是随机排序的

touch1.startPoint,touch1.currentPoint,touch2.startPoint,touch2.currentPoint

那么:

startPoint.x = (touch2.startPoint.x + touch1.startPoint.x) / 2;    //中心点

startPoint.y = (touch2.startPoint.y + touch2.startPoint.y) / 2;    //中心点

currentPoint 与 startPoint相同

2.缩放

缩放的主要思路是移动后触摸两点的距离(向量)与开始两点的距离比,缩放必须要多点触摸,同样,我们需要记录4个点

touch1.startPoint,touch1.currentPoint,touch2.startPoint,touch2.currentPoint

那么,

vector1 = sqrt( (touch2.startPoint.x – touch1.startPoint.x)^2 + (touch2.startPoint.y – touch1.startPoint.y)^2 );    //起始向量长度

vector2 = sqrt( (touch2.currentPoint.x – touch1.currentPoint.x)^2 + (touch2.currentPoint.y – touch1.currentPoint.y)^2 );

于是,缩放

float scale = vector2 / vector1;    //在这里我们会使用x,y使用同一个缩放值

可以调用 CGAffineTransformMakeScale(scale,scale) 来进行缩放了。

3.旋转

旋转的主要思路是移动后触摸两点的向量相对于开始两点的偏移角度(弧度),需要必须多点触摸,同样我们需要记录4个点

touch1.startPoint,touch1.currentPoint,touch2.startPoint,touch2.currentPoint

那么:

angle1 = atan( (touch2.startPoint.y – touch1.startPoint.y) / (touch2.startPoint.x – touch1.startPoint.x) );    //求起始向量相对于x轴的角度

angle2 = atan( (touch2.currentPoint.y – touch1. currentPoint.y) / (touch2. currentPoint.x – touch1. currentPoint.x) );    //求当前向量相对于x轴的角度

 

那么 偏移角度

angle = angle2 – angle1;

可以调用CGAffineTransformMakeRotation(angle)实现旋转.
原文地址:https://www.cnblogs.com/gaoxiao228/p/2483435.html