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

hot*_*aw2 43 math core-graphics cgaffinetransform ios

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

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

小智 119

围绕点(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));
Run Code Online (Sandbox Code Playgroud)

您可能需要插入-a而不是a,具体取决于您是要将旋转顺时针还是逆时针旋转.此外,您可能需要插入-y而不是y,具体取决于您的坐标系是否颠倒.

此外,您可以使用以下三行代码完成相同的操作:

CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
transform = CGAffineTransformRotate(transform, a);
transform = CGAffineTransformTranslate(transform,-x,-y);
Run Code Online (Sandbox Code Playgroud)

如果您将此应用于视图,您还可以通过CGAffineTransformMakeRotation(a)简单地使用旋转变换,前提是您设置视图的图层的anchorPoint属性以反映您想要旋转的点.但是,听起来你对将它应用于视图并不感兴趣.

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

PS我也想提醒任何读到这篇文章的人,"affine"的发音是短的"a",如"ask",而不是长的"a",如"able".我甚至听说过苹果员工在WWDC会谈中误解了它.

  • 如果你打算给出关于发音的提示,那么你还应该指定它是"精细"还是"精细"中的"精细".但也许我是唯一一个错误的人.: - / (2认同)
  • 当旋转超过180度时,此功能不起作用,该功能转换为最终结果,始终以最短的方式旋转 (2认同)

小智 6

对于 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)
Run Code Online (Sandbox Code Playgroud)