关于坐标变换要记住的一点——嗯,要记住的一件事——是你不是在操纵对象,就像图形编辑器中的变换命令一样;你正在操纵空间本身。
想象一下,该设备通过鹅颈臂悬挂在桌子上,并固定在适当的位置。坐标变换使桌子四处移动(平移),并以一种或另一种方式转动(旋转),甚至挤压和拉伸它(缩放)。
关于坐标变换要记住的另一件事是变换总是相对于原点。想象一下,你的办公桌从它的一个角开始——对应于你视图的一个角——就在你的视图在屏幕上结束的角的正下方。平移移动桌子的一角,桌子的其余部分也随之移动,在屏幕下方以一种或另一种方式滑动。旋转使桌子绕过那个角落。
还有一件事:转型影响未来,而不是过去。画一些东西然后试图改变它是行不通的,因为你没有改变你画的东西,你改变了你要画的空间。因此,我们需要先移动桌子,然后才能将图像放置在正确的位置。
(我提到最后一部分是因为您有几个转换命令会立即被您的CGContextRestoreGState
调用恢复。它们之间没有绘图可以影响。)
所以,让我们从图像的未旋转矩形开始。
CGRect imageRect = { pointWhereYouWantTheImageCentered, doodad.size };
现在,CGContextDrawImage
需要一个矩形,但是,如您所知,它将从该矩形的左下角而不是中心绘制图像。(因此整个练习。)
所以,这就是你要做的。在此结束时,您将不会在上面显示的那个点绘制图像,而是在零点- 即在桌子的最角落。(不是以角落为中心,而是图像的角落在桌子的角落。)
这将如何运作?这需要一些设置。你将不得不移动你的办公桌。
首先,您需要将办公桌向上和向右移动,直到办公桌的原点角位于所需的中心点:
CGContextTranslateCTM(context, imageRect.origin.x, imageRect.origin.y);
然后您进行旋转(将桌子围绕其原点转角):
CGContextRotateCTM(context, angleInRadians);
然后将桌子向下和向左移动图像宽度和高度的一半:
CGContextTranslateCTM(context, imageRect.size.width * -0.5, imageRect.size.height * -0.5);
然后,最后,将图像放在桌子的角落。
CGContextDrawImage(context, (CGRect){ CGPointZero, imageRect.size }, [doodad CGImage]);
随着您的办公桌如此移动,该矩形的中心位于屏幕上您希望图像居中的点的正下方,因此图像如此居中。