最近看《iOS-Core-Animation-Advanced-Techniques》。在仿射变换中的混合变换里,提到了以下几个函数:
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)
在看前面的仿射变换的时候,我知道了经过仿射变换,点的位置是经过以下矩阵的计算来得到的。
即
那以下几个函数是经过怎样的矩阵变换来计算变换后点的位置呢?
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)
在苹果的官方文档上面我查到了以下资料:
这样看来,混合变换的几个函数,就是它们两个仿射变换矩阵想乘的结果用来做变换。
为了验证这个假设,我写了段简单的代码。
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"initial frame: %@", NSStringFromCGRect(self.outerView.frame));
NSLog(@"initial bounds: %@", NSStringFromCGRect(self.outerView.bounds));
NSLog(@"initial center: %@", NSStringFromCGPoint(self.outerView.center));
NSLog(@"initial anchorPoint: %@", NSStringFromCGPoint(self.outerView.layer.anchorPoint));
//消除anchorPoint对计算结果的影响
CGRect frame = self.outerView.frame;
self.outerView.layer.anchorPoint = CGPointMake(0, 0);
self.outerView.frame = frame;
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformScale(transform, 0.5, 0.5);
transform = CGAffineTransformTranslate(transform, 270, 0);
self.outerView.layer.affineTransform = transform;
NSLog(@"after frame: %@", NSStringFromCGRect(self.outerView.frame));
NSLog(@"after bounds: %@", NSStringFromCGRect(self.outerView.bounds));
NSLog(@"after center: %@", NSStringFromCGPoint(self.outerView.center));
NSLog(@"after anchorPoint: %@", NSStringFromCGPoint(self.outerView.layer.anchorPoint));
}
运行结果如下:
2015-06-15 23:13:44.334 CoreAnimationDemo[16716:750105] initial frame: {{0, 0}, {100, 100}}
2015-06-15 23:13:44.335 CoreAnimationDemo[16716:750105] initial bounds: {{0, 0}, {100, 100}}
2015-06-15 23:13:44.335 CoreAnimationDemo[16716:750105] initial center: {50, 50}
2015-06-15 23:13:44.335 CoreAnimationDemo[16716:750105] initial anchorPoint: {0.5, 0.5}
2015-06-15 23:13:44.336 CoreAnimationDemo[16716:750105] after frame: {{135, 0}, {50, 50}}
2015-06-15 23:13:44.336 CoreAnimationDemo[16716:750105] after bounds: {{0, 0}, {100, 100}}
2015-06-15 23:13:44.336 CoreAnimationDemo[16716:750105] after center: {0, 0}
2015-06-15 23:13:44.337 CoreAnimationDemo[16716:750105] after anchorPoint: {0, 0}
这段代码的作用是先缩小一半,然后右移270点。
缩小一半的矩阵为A:
右移270点的矩阵为B:
那么transform = CGAffineTransformTranslate(transform, 270, 0);
到底是A*B还是B*A呢?
我们用点(0,0)来试验一下,当A*B时,我们计算出转换后的坐标为(270,0);当B*A时,计算出转换后的坐标为(135,0)。我们看下我们代码的运行结果,可以看出正确的结果是(135,0)。即应该是B*A。
由此,我们得出结论,以下函数都是新的矩阵
*先前的矩阵t
来进行混合变换的。
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)