Android绘制时的坐标系变换

坐标系的变换就是变换前后的映射关系。只要理清这个变换关系就什么都明白了。

现在从屏幕坐标系开始(即以屏幕左上角为原点的坐标系)

变换到窗口坐标系:假如窗口左上角的坐标(下面都是指当前坐标系中的坐标)为(0, 20)

如:坐标系平移:Canvas#translate(0, 20);则Canvas当前的坐标系是窗口坐标系(即以窗口左上角为原点)。变换的意义何在,方便我们在绘图时更加方便,如我们需要以(20,20)(窗口坐标系)为圆心绘制一个圆,在没有变换之前(在屏幕坐标系),代码为:Canvas.drawCircle(0+20, 20+20,int半径,Paint),因为最终绘制是要映射到屏幕坐标的,因为屏幕坐标应该是跟物理屏幕有对应关系的,可能是对应的坐标对应了屏幕中的某个像素点。所以你要操作哪个像素点,你需要指明在屏幕坐标系中的坐标。在Canvas中做了坐标变换后,如刚才变换到了窗口坐标系,那么你在使用Canvas工具绘图时,在指定绘制像素点的坐标时,你只需在窗口坐标系中指定坐标就行,如上面所说画圆,直接Canvas.drawCircle(20, 20, int半径, Paint)即可,然后画到画布(与Canvas关联的Surface)去的时候,会根据之前的变换,计算出你要绘制的点在屏幕坐标系中的坐标。所以在旋转,放大,平移滑动,并不是画布在动让你去画,而是通过坐标系变换,让你点经过计算对应到屏幕坐标系中,而变换过程,Canvas中已经封装了,你只需指定变换类型和给定必要的参数即可。其他变换过程一样,都是基于Canvas原有的变换基础上变换的,这样才能将点正确对应屏幕坐标系上。


下面看看通过坐标变换实现平移(看上图):

实现内容向上移动,只需把绘制坐标系上移即可。就加上一行变换坐标的代码即可。要旋转某个角度一样,把坐标系旋转了,加一行代码即可,即你像平时在端正的坐标系上画东西一样,但是Canvas在绘制前,将你绘制的每个点的坐标都根据之前的变换操作,作了一次函数映射,使得你画的整个图形都是旋转了某个角度的。


那么放大,平移等各种变换都是类似,只是映射函数不一样罢了。如:放大的前后映射关系是(假如放大5倍)y= 5x;y为变换后的坐标值,x为变换前的坐标值,即你在代码指定的坐标值。而平移则是(假如是平移10dp)y = x + 10。而旋转的映射函数可能复杂点,没有研究过,可自行查看代码或百度。而变化的叠加,也是一次函数的运算,如放大后平移,映射函数为y = 5(x + 10);


变换的保存和恢复(变换不止是坐标变换,还有裁剪区域等):

save()/restore()可以嵌套使用。如:

canvas.save();

.......//各种变换和绘制

canvas.save();

........//各种变换和绘制

canvas.restore();

....//各种绘制

canvas.restore();

以下是方法的解释:

Canvas.save();//保存当前Canvas的状态

Canvas.restore();//恢复到上次保存的那个状态(上次指的是最近保存的一次),Canvas中应该在一个栈中保存了所有save()时的状态。

Canvas.restoreToCount(int count);//恢复到对应的状态,就是canvas.save()返回的值的那个节点的状态。

如into restoreTo = canvas.save();

..........中间经历了n次变换和无数上次保存

canvas.restoreToCount(restoreTo);


你可能感兴趣的