代碼地址和動(dòng)效圖
?先上代碼和圖.
?用到了什么
如果你寫過自定義view,那么你一定聽過說過Matrix,Matrix就是一個(gè)3*3的矩陣,他可以負(fù)責(zé)圖像的旋轉(zhuǎn),位移等操作.如果你對Matrix不太了解,可以去看看Matrix相關(guān).
Matrix 原理
Matrix 詳解
而Camera則是能提供"3D 版的Matrix",也就是說一個(gè)平面,可以通過Camera進(jìn)行旋轉(zhuǎn)甚至左右前后移動(dòng),然后會(huì)得到一個(gè)Matrix,該Matrix就可以讓平面產(chǎn)生形變某弦,從而達(dá)到3D的效果.
Matrix Camera
如何實(shí)現(xiàn)
如何畫出一個(gè)立方體
主要分為2步
- 把面旋轉(zhuǎn)成水平或者垂直
- 旋轉(zhuǎn)完畢后 把面移到對應(yīng)的位置
因?yàn)?D坐標(biāo)系和2D坐標(biāo)系都位于屏幕左上角,所以要調(diào)整下中心點(diǎn).所以3D坐標(biāo)系和2D坐標(biāo)系都要調(diào)整中心點(diǎn).
/**
*
* @param position 面的序號(hào) 0~3 面的序號(hào)后面提到
* @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)系原點(diǎn)默認(rèn)是屏幕左上角, 故調(diào)整3D中心點(diǎn)洲赵。而前乘再后乘,是matrix的一個(gè)小技巧
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();
}
確定各個(gè)面和旋轉(zhuǎn)軸
各個(gè)面的序號(hào)
結(jié)合動(dòng)效圖,可以看到立方體在旋轉(zhuǎn)的過程中,最多只能看到3個(gè)面.
首先給各個(gè)面標(biāo)上序號(hào).
0,1,2,3是立方體的旋轉(zhuǎn)的面(旋轉(zhuǎn)過程中最多展示2個(gè)面,2,3在下面的圖中無法看到,用箭頭標(biāo)示).
4是立方體的側(cè)面(始終展示).
4的對立面始終不展示我就不標(biāo)出來了
可以看到上圖的立方體是有傾斜角,初始狀態(tài)的立方體是
坐標(biāo)系
android的3D的坐標(biāo)系和2D是有一些不一樣的.在Matrix Camera提到過.
而該立方體的坐標(biāo)系是:
- 0面中心為原點(diǎn)
- x,y軸正方向分別是0面右方和上方
- 0面朝里是z軸正方向
?開始旋轉(zhuǎn)
繞Y軸旋轉(zhuǎn)45度
初始狀態(tài)的立方體有一定的傾斜角,這是因?yàn)榱⒎襟w按Y軸旋轉(zhuǎn)45度.要不然我們只能看到一個(gè)平面的正方體.
繞X軸進(jìn)行旋轉(zhuǎn)動(dòng)畫.
//degree 是旋轉(zhuǎn)角度
void drawCube(int position,Canvas canvas) {
camera.save();
camera.rotateY(45);
camera.rotateX(degree + position % 2 * 90);
...
}
各個(gè)面畫得先后順序
- 0~3面的繪畫順序根據(jù)旋轉(zhuǎn)角度做了特例判斷
- 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的使用