简单的自定义View——矩阵、Camera变换

来源:互联网 发布:atlas.ti7软件下载 编辑:程序博客网 时间:2024/04/28 08:54

简单的自定义View——矩阵、Camera变换

老规矩先看图

这里写图片描述


先了解下Matrix和Camera

Matrix——顾名思义就是矩阵的意思

  • Matrix常用于2D变换,比如旋转、平移、缩放等,具体方法如下
  • setTranslate(float dx,float dy):控制Matrix进行位移。
  • setSkew(float kx,float ky):控制Matrix进行倾斜,kx、ky为X、Y方向上的比例。
  • setSkew(float kx,float ky,float px,float py):控制Matrix以px、py为轴心进行倾斜,kx、ky为X、Y方向上的倾斜比例。
  • setRotate(float degrees):控制Matrix进行depress角度的旋转,轴心为(0,0)。
  • setRotate(float degrees,float px,float py):控制Matrix进行depress角度的旋转,轴心为(px,py)。
  • setScale(float sx,float sy):设置Matrix进行缩放,sx、sy为X、Y方向上的缩放比例。
  • setScale(float sx,float sy,float px,float py):设置Matrix以(px,py)为轴心进行缩放,sx、sy为X、Y方向上的缩放比例。

Camera——常用于3D变换

  • 1,camera位于坐标点(0,0),也就是视图的左上角;
  • 2,camera.translate(10, 20, 30)的意思是把观察物体右移10,上移20,向前移30(即让物体远离camera,这样物体将会变小);
  • 3,camera.rotateX(45)的意思是绕x轴顺时针旋转45度。举例来说,如果物体中间线和x轴重合的话,绕x轴顺时针旋转45度就是指物体上半部分向里翻转,下半部分向外翻转;
  • 4,camera.rotateY(45)的意思是绕y轴顺时针旋转45度。举例来说,如果物体中间线和y轴重合的话,绕y轴顺时针旋转45度就是指物体右半部分向里翻转,左半部分向外翻转;
  • 5,camera.rotateZ(45)的意思是绕z轴顺时针旋转45度。举例来说,如果物体中间线和z轴重合的话,绕z轴顺时针旋转45度就是指物体上半部分向左翻转,下半部分向右翻转;

要了解更多,请百度,我就不复制过来了。


接着来看下实际应用

接着用上次做的时钟表盘:http://blog.csdn.net/qq970259858/article/details/53053235

增加如下方法即可:

3D变换

    // 3D变换    private void rotateCanvas(Canvas canvas) {        mMatrix.reset();        mCamera.save();        // 沿x轴顺时针旋转        mCamera.rotateX(mCanvasRotateX);        // 沿y轴顺时针旋转        mCamera.rotateY(mCanvasRotateY);        mCamera.getMatrix(mMatrix);        mCamera.restore();        // 将变换参考点移置中心        mMatrix.preTranslate(-x, -y);        mMatrix.postTranslate(x, y);        canvas.concat(mMatrix);    }

控制变换度

    // 控制变换度    private void rotateCanvasWhenMove(float xMove, float yMove) {        float dx = xMove - x;        float dy = yMove - y;        float percentX = dx / x;        float percentY = dy / y;        if (percentX > 1f) {            percentX = 1f;        } else if (percentX < -1f) {            percentX = -1f;        }        if (percentY > 1f) {            percentY = 1f;        } else if (percentY < -1f) {            percentY = -1f;        }        //最终得到指定范围的最大变化度        mCanvasRotateY = mCanvasMaxRotateDegree * percentX;        mCanvasRotateX = -(mCanvasMaxRotateDegree * percentY);    }

重写onTouchEvent

    @Override    public boolean onTouchEvent(MotionEvent event) {        float eventX = event.getX();        float eventY = event.getY();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                rotateCanvasWhenMove(eventX, eventY);                invalidate();                return true;            case MotionEvent.ACTION_MOVE:                rotateCanvasWhenMove(eventX, eventY);                invalidate();                break;            case MotionEvent.ACTION_UP:                mCanvasRotateX = 0;                mCanvasRotateY = 0;                invalidate();                return true;            default:                return true;        }        return super.onTouchEvent(event);    }

最后看下onDraw绘制

需要注意的一点:变换一定要在绘制之前。

    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        initClock();        rotateCanvas(canvas); //  必须在绘制之前变换        drawBigCircle(canvas);        drawkedu(canvas);        drawNumber(canvas);        drawHour(canvas, hourAngle);        drawMinute(canvas, minuteAngle);        drawSecond(canvas, secondAngle);        drawSmallCircle(canvas);        postInvalidateDelayed(1000);    }

完整源码下载地址https://github.com/LiLinXiang/ClockView

0 0
原创粉丝点击