绕一点旋转的一步仿射变换?

时间:2011-11-26 02:38:54

标签: ios math core-graphics cgaffinetransform

如何使用CGAffineTransformMake()加上math.h触发函数(如sin(),cos()等),围绕角度a的x,y点旋转进行Core Graphics仿射变换。,而且没有其他CG电话。

其他答案似乎是使用多个堆叠变换或多步变换来移动,旋转和移动,使用多个Core Graphics调用。这些答案不符合我的具体要求。

5 个答案:

答案 0 :(得分:113)

围绕点(x,y)的角度α的旋转对应于仿射变换:

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)简单地使用旋转变换,前提是您设置视图的图层的anchorPoint属性以反映您想要旋转的点。但是,听起来你似乎对将它应用于视图不感兴趣。

最后,如果您将此应用于非欧几里德2D空间,您可能根本不需要仿射变换。仿射变换是欧几里德空间的等距,意味着它们保持标准的欧几里德距离以及角度。如果你的空间不是欧几里德,那么你想要的变换实际上可能不是仿射,或者如果它是仿射的,那么旋转的矩阵可能不像我上面用sin和cos写的那么简单。例如,如果你处于双曲线空间,你可能需要使用双曲线触发函数sinh和cosh,以及公式中不同的+和 - 符号。

P.S。我还想提醒任何读到这篇文章的人,“仿射”的发音是用短语“a”和“ask”一样,而不是长篇“a”,如“有能力”。我甚至听说过苹果公司员工在WWDC会谈中误解了它。

答案 1 :(得分:2)

对于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)

答案 2 :(得分:1)

对于像我这样的人来说,为了填充包含的框架,正在努力寻找旋转图像并正确缩放图像的完整解决方案,几个小时之后,这是我拥有的最完整,最完美的解决方案获得。

这里的技巧是在涉及任何转换(比例和旋转)之前转换参考点。之后,您必须连接两个转换才能获得完整的仿射变换。

我已将整个解决方案打包在您可以gist here的CIFilter子类中。

遵循相关的代码部分:

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);

答案 3 :(得分:0)

点击此链接:Rotating an iPhone View Around a Point。它可能会帮助你。在文章的底部,有一个标题为“更改锚点”的部分。这可能最适合您的需求,但必须进行一些补偿才能抵消视图。

答案 4 :(得分:-1)

使用视图的图层和锚点。 e.g。

view.layer.anchorPoint = CGPoint(x:0,y:1.0)