如何畫出一個旋轉(zhuǎn)的立方體

代碼地址和動效圖

?先上代碼和圖.

github地址

?cube

?用到了什么

如果你寫過自定義view,那么你一定聽過說過Matrix,Matrix就是一個3*3的矩陣,他可以負(fù)責(zé)圖像的旋轉(zhuǎn),位移等操作.如果你對Matrix不太了解,可以去看看Matrix相關(guān).
Matrix 原理
Matrix 詳解

而Camera則是能提供"3D 版的Matrix",也就是說一個平面,可以通過Camera進(jìn)行旋轉(zhuǎn)甚至左右前后移動,然后會得到一個Matrix,該Matrix就可以讓平面產(chǎn)生形變,從而達(dá)到3D的效果.
Matrix Camera

如何實現(xiàn)

如何畫出一個立方體

主要分為2步

  1. 把面旋轉(zhuǎn)成水平或者垂直
  2. 旋轉(zhuǎn)完畢后 把面移到對應(yīng)的位置
    因為3D坐標(biāo)系和2D坐標(biāo)系都位于屏幕左上角,所以要調(diào)整下中心點.所以3D坐標(biāo)系和2D坐標(biāo)系都要調(diào)整中心點.
    /**
     * 
     * @param position 面的序號 0~3 面的序號后面提到
     * @param canvas 
     */
    void drawCube(int position,Canvas canvas) {
        camera.save();
        //1.旋轉(zhuǎn)成水平或者垂直
        camera.rotateX(position % 2 * 90);
        //2.旋轉(zhuǎn)完畢后 把面移到對應(yīng)的位置
        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坐標(biāo)系原點默認(rèn)是屏幕左上角, 故調(diào)整3D中心點。而前乘再后乘,是matrix的一個小技巧
        matrix.preTranslate(-viewWidth / 2, -viewHeight / 2);
        matrix.postTranslate(viewWidth / 2, viewHeight / 2);


        //4. 調(diào)整2D坐標(biāo)系 并且畫出正方體
        canvas.save();
        canvas.concat(matrix);
        canvas.translate(viewWidth / 2, viewHeight / 2);
        paint.setColor(colors[position % 2]);
        canvas.drawRect(rectF, paint);
        canvas.restore();
    }

確定各個面和旋轉(zhuǎn)軸

各個面的序號

結(jié)合動效圖,可以看到立方體在旋轉(zhuǎn)的過程中,最多只能看到3個面.
首先給各個面標(biāo)上序號.
0,1,2,3是立方體的旋轉(zhuǎn)的面(旋轉(zhuǎn)過程中最多展示2個面,2,3在下面的圖中無法看到,用箭頭標(biāo)示).
4是立方體的側(cè)面(始終展示).
4的對立面始終不展示我就不標(biāo)出來了


Paste_Image.png

可以看到上圖的立方體是有傾斜角,初始狀態(tài)的立方體是


Paste_Image.png
坐標(biāo)系

android的3D的坐標(biāo)系和2D是有一些不一樣的.在Matrix Camera提到過.
而該立方體的坐標(biāo)系是:

  1. 0面中心為原點
  2. x,y軸正方向分別是0面右方和上方
  3. 0面朝里是z軸正方向

?開始旋轉(zhuǎn)

繞Y軸旋轉(zhuǎn)45度

初始狀態(tài)的立方體有一定的傾斜角,這是因為立方體按Y軸旋轉(zhuǎn)45度.要不然我們只能看到一個平面的正方體.

繞X軸進(jìn)行旋轉(zhuǎn)動畫.

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

各個面畫得先后順序

  1. 0~3面的繪畫順序根據(jù)旋轉(zhuǎn)角度做了特例判斷
  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();

基本上就這樣了,主要是練習(xí)了下matrix的使用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容