自定义View-坐标转换

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_32113133/article/details/66971655
坐标转换
默认情况下,画布坐标的原点就是绘图区的左上角,向左为负,向右为正,向上为负,向下为正,但是通过 Canvas ᨀ供的方法可以对坐标进行转换。转换的方式主要有 4 种:平移、旋转、缩放和拉斜:

1)平移:

public void translate(float dx,float dy)
坐标平移,在当前原点的基础上水平移动 dx 个距离,垂直移动 dy 个距离,正负符号决定方向。坐标原点改变后,所有的坐标都是以新的原点为参照进行定位。下面两段代码是等效的:
代码段 1:
canvas.drawPoint(10, 10, paint); 

代码段 2:

canvas.translate(10, 10);
canvas.drawPoint(0, 0, paint);


2)旋转:

public void rotate(float degrees)

将画布的坐标以当前原点为中心旋转指定的角度,如果角度为正,则为顺时针旋转,否则为逆时针旋转。


public final void rotate(float degrees,float px,float py)
以点(px, py)为中心对画布坐标进行旋转 degrees 度,为正表示顺时针,为负表示逆时针。


3)缩放:

public void scale(float sx,float sy)
缩放画布的坐标,sx、sy 分别是 x 方向和 y 方向的缩放比例,小于 1 表示缩小,等于1 表示不变,大于 1 表示放大。画布缩放后,绘制在画布上的图形也会等比例缩放。

缩放的单位是倍数,比如 sx 为 0.5 时,就是在 x 方向缩小 0.5 倍。


public final void scale(float sx,float sy,float px,float py)
以(px,py)为中心对画布进行缩放。


4)拉斜:

public void skew(float sx,float sy)
将画布分别在 x 方向和 y 方向拉斜一定的角度,sx 为 x 方向倾斜角度的 tan 值,sy 为y 方向倾斜角度的 tan 值,比如我们打算在 X 轴方向上倾斜 45 度,则 tan45=1,写
成:canvas.skew(1, 0)。


坐标转换后,后面的图形绘制功能将跟随新坐标,转换前已经绘制的图形不会有任何的变化。另外,为了能恢复到坐标变化之前的状态,Canvas 定义了两个方法用于保存现场和恢复现场:
public int save ()

保存现场


public void restore ()

恢复现场到 save()执行之前的状态。


MainActivity:

public class CoordinateView extends View {
    public CoordinateView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(2);//设置边的宽度
        paint.setStyle(Paint.Style.STROKE);//设置画笔的样式为描边
        //保存现场
        canvas.save();
        for (int i = 0; i < 5; i++) {
            canvas.drawRect(0, 0, 150, 150, paint);
            canvas.translate(30, 30);
        }
        //恢复现场
        canvas.restore();//恢复现场到 save()执行之前的状态。
        //平移坐标,让接下来的图形绘制在上一次图形的下面
        canvas.translate(0, 300);
        canvas.save();
        for (int i = 0; i < 5; i++) {
            canvas.drawRect(0, 0, 400, 400, paint);
            canvas.scale(0.9f, 0.9f, 200, 200);
        }
        canvas.restore();//恢复现场到 save()执行之前的状态。 也就是在矩形的下面
        //平移坐标,让接下来的图形绘制在上一次图形的下面
        canvas.translate(0, 450);
        canvas.save();
        canvas.drawCircle(200, 200, 200, paint);
        for (int i = 0; i < 12; i++) {
            canvas.drawLine(350, 200, 400, 200, paint);
            canvas.rotate(30, 200, 200);
        }
        canvas.restore();
    }
}

结果:



猜你喜欢

转载自blog.csdn.net/qq_32113133/article/details/66971655