代码地址和动效图
�先上代码和图.
�用到了什么
如果你写过自定义view,那么你一定听过说过Matrix,Matrix就是一个3*3的矩阵,他可以负责图像的旋转,位移等操作.如果你对Matrix不太了解,可以去看看Matrix相关.
Matrix 原理
Matrix 详解
而Camera则是能提供"3D 版的Matrix",也就是说一个平面,可以通过Camera进行旋转甚至左右前后移动,然后会得到一个Matrix,该Matrix就可以让平面产生形变,从而达到3D的效果.
Matrix Camera
如何实现
如何画出一个立方体
主要分为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的对立面始终不展示我就不标出来了
可以看到上图的立方体是有倾斜角,初始状态的立方体是
坐标系
android的3D的坐标系和2D是有一些不一样的.在Matrix Camera提到过.
而该立方体的坐标系是:
- 0面中心为原点
- x,y轴正方向分别是0面右方和上方
- 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);
...
}
各个面画得先后顺序
- 0~3面的绘画顺序根据旋转角度做了特例判断
- 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的使用