如何画出一个旋转的立方体

代码地址和动效图

�先上代码和图.

github地址

�cube

�用到了什么

如果你写过自定义view,那么你一定听过说过Matrix,Matrix就是一个3*3的矩阵,他可以负责图像的旋转,位移等操作.如果你对Matrix不太了解,可以去看看Matrix相关.
Matrix 原理
Matrix 详解

而Camera则是能提供"3D 版的Matrix",也就是说一个平面,可以通过Camera进行旋转甚至左右前后移动,然后会得到一个Matrix,该Matrix就可以让平面产生形变,从而达到3D的效果.
Matrix Camera

如何实现

如何画出一个立方体

主要分为2步

  1. 把面旋转成水平或者垂直
  2. 旋转完毕后 把面移到对应的位置
    因为3D坐标系和2D坐标系都位于屏幕左上角,所以要调整下中心点.所以3D坐标系和2D坐标系都要调整中心点.
    /**
     * 
     * @param position 面的序号 0~3 面的序号后面提到
     * @param canvas 
     */
    void drawCube(int position,Canvas canvas) {
        camera.save();
        //1.旋转成水平或者垂直
        camera.rotateX(position % 2 * 90);
        //2.旋转完毕后 把面移到对应的位置
        switch (position) {
            case 0:
                break;
            case 1:
                camera.translate(0,100,100);
                break;
            case 2:
                camera.translate(0,0,200);
                break;
            case 3:
                camera.translate(0,100,-100);
                break;

        }
        camera.getMatrix(matrix);
        camera.restore();

        //3.由于3D坐标系原点默认是屏幕左上角, 故调整3D中心点。而前乘再后乘,是matrix的一个小技巧
        matrix.preTranslate(-viewWidth / 2, -viewHeight / 2);
        matrix.postTranslate(viewWidth / 2, viewHeight / 2);


        //4. 调整2D坐标系 并且画出正方体
        canvas.save();
        canvas.concat(matrix);
        canvas.translate(viewWidth / 2, viewHeight / 2);
        paint.setColor(colors[position % 2]);
        canvas.drawRect(rectF, paint);
        canvas.restore();
    }

确定各个面和旋转轴

各个面的序号

结合动效图,可以看到立方体在旋转的过程中,最多只能看到3个面.
首先给各个面标上序号.
0,1,2,3是立方体的旋转的面(旋转过程中最多展示2个面,2,3在下面的图中无法看到,用箭头标示).
4是立方体的侧面(始终展示).
4的对立面始终不展示我就不标出来了


Paste_Image.png

可以看到上图的立方体是有倾斜角,初始状态的立方体是


Paste_Image.png
坐标系

android的3D的坐标系和2D是有一些不一样的.在Matrix Camera提到过.
而该立方体的坐标系是:

  1. 0面中心为原点
  2. x,y轴正方向分别是0面右方和上方
  3. 0面朝里是z轴正方向

�开始旋转

绕Y轴旋转45度

初始状态的立方体有一定的倾斜角,这是因为立方体按Y轴旋转45度.要不然我们只能看到一个平面的正方体.

绕X轴进行旋转动画.

      //degree 是旋转角度
    void drawCube(int position,Canvas canvas) {
        camera.save();
        camera.rotateY(45);
        camera.rotateX(degree + position % 2 * 90);
                ...
    }

各个面画得先后顺序

  1. 0~3面的绘画顺序根据旋转角度做了特例判断
  2. 4面最后画
float degree = value * 360;
        if(degree >= 0 && degree < 90 ) {
            drawCube(1,canvas);
            drawCube(0,canvas);
        }

        if(degree >= 90 && degree < 135) {
            drawCube(2,canvas);
            drawCube(1,canvas);
        }

        if(degree >= 135 && degree < 180) {
            drawCube(1,canvas);
            drawCube(2,canvas);
        }

        if(degree >= 180 && degree < 225) {
            drawCube(3,canvas);
            drawCube(2,canvas);
        }

        if(degree >= 225 && degree < 270) {
            drawCube(2,canvas);
            drawCube(3,canvas);
        }

        if(degree >= 270 && degree <= 360) {
            drawCube(3,canvas);
            drawCube(0,canvas);
        }

        camera.save();
        camera.rotateY(45);
        camera.rotateX(value * 360);
        camera.rotateY(90);
        camera.translate(100,0,100);
        camera.getMatrix(matrix);
        camera.restore();

        // control center
        matrix.preTranslate(-viewWidth / 2, -viewHeight / 2);
        matrix.postTranslate(viewWidth / 2, viewHeight / 2);

        canvas.save();
        canvas.concat(matrix);
        canvas.translate(viewWidth / 2, viewHeight / 2);
        paint.setColor(0xFFFDFDE3);
        canvas.drawRect(rectF, paint);
        canvas.restore();

基本上就这样了,主要是练习了下matrix的使用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容