我如何使用单个CGAffineTransformMake()调用以及数学函数如sin(), cos()等,而不使用其他CG调用,制作一个绕点(x, y)旋转角度a的Core Graphics仿射变换。
其他答案似乎是关于使用多个堆叠的变换或多步变换来移动、旋转和移动,使用多个Core Graphics调用。这些答案不符合我的特定要求。
我如何使用单个CGAffineTransformMake()调用以及数学函数如sin(), cos()等,而不使用其他CG调用,制作一个绕点(x, y)旋转角度a的Core Graphics仿射变换。
其他答案似乎是关于使用多个堆叠的变换或多步变换来移动、旋转和移动,使用多个Core Graphics调用。这些答案不符合我的特定要求。
绕点(x,y)旋转角度a对应于仿射变换:
CGAffineTransform transform = CGAffineTransformMake(cos(a),sin(a),-sin(a),cos(a),x-x*cos(a)+y*sin(a),y-x*sin(a)-y*cos(a));
根据你想要的旋转方向,你可能需要使用-a而不是a。此外,根据你的坐标系统是否倒置,你可能需要使用-y而不是y。
另外,你可以使用以下三行代码实现完全相同的效果:
CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
transform = CGAffineTransformRotate(transform, a);
transform = CGAffineTransformTranslate(transform,-x,-y);
如果您要将此应用于视图,则还可以通过CGAffineTransformMakeRotation(a)使用旋转变换,只需设置视图的图层锚点属性以反映您要围绕旋转的点即可。但是,听起来您并不想将其应用于视图。针对Swift 4版本
print(x, y) // where x,y is the point to rotate around
let degrees = 45.0
let transform = CGAffineTransform(translationX: x, y: y)
.rotated(by: degrees * .pi / 180)
.translatedBy(x: -x, y: -y)
对于像我这样的人,他们正在苦苦寻找完整的解决方案来旋转并适当缩放图像,以便填充包含框架,在几个小时后,这是我得到的最完整和无瑕疵的解决方案。
这里的技巧是在任何变换(包括比例和旋转)之前翻译参考点。之后,您必须连接两个变换以获得完整的仿射变换。
我已经将整个解决方案打包在一个CIFilter子类中,您可以在gist here。
以下是相关代码部分:
CGFloat a = _inputDegree.floatValue;
CGFloat x = _inputImage.extent.size.width/2.0;
CGFloat y = _inputImage.extent.size.height/2.0;
CGFloat scale = [self calculateScaleForAngle:GLKMathRadiansToDegrees(a)];
CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
transform = CGAffineTransformRotate(transform, a);
transform = CGAffineTransformTranslate(transform,-x,-y);
CGAffineTransform transform2 = CGAffineTransformMakeTranslation(x, y);
transform2 = CGAffineTransformScale(transform2, scale, scale);
transform2 = CGAffineTransformTranslate(transform2,-x,-y);
CGAffineTransform concate = CGAffineTransformConcat(transform2, transform);
以下是一些关于围绕锚点旋转的便捷方法:
extension CGAffineTransform {
init(rotationAngle: CGFloat, anchor: CGPoint) {
self.init(
a: cos(rotationAngle),
b: sin(rotationAngle),
c: -sin(rotationAngle),
d: cos(rotationAngle),
tx: anchor.x - anchor.x * cos(rotationAngle) + anchor.y * sin(rotationAngle),
ty: anchor.y - anchor.x * sin(rotationAngle) - anchor.y * cos(rotationAngle)
)
}
func rotated(by angle: CGFloat, anchor: CGPoint) -> Self {
let transform = Self(rotationAngle: angle, anchor: anchor)
return self.concatenating(transform)
}
}
view.layer.anchorPoint = CGPoint(x:0,y:1.0)
anchorPoint
会影响整个图层/视图的变换坐标空间,从而影响到与之无关的布局、动画等。 - John Estropia
CGAffineTransformMake()
这个函数进行单独调用呢?堆叠的调用会产生完全相同的结果,只不过以一种可读且有意义的方式展示。如果你真的想要在一个调用中完成,那么你最终只是在重复使用堆叠调用中所使用的相同数学运算,而没有任何好处。 - Lily Ballard