Android的3D旋转

见过没有用opengl的3D动画,看了一下,是用的Camera实现的,内部机制实际上还是opengl,不过大大简化了使用。
Camera就像一个摄像机,一个物体在原地不动,然后我们带着这个摄像机四处移动,在摄像机里面呈现出来的画面,就会有立体感,就可以从各个角度观看这个物体。
它有旋转、平移的一系列方法,实际上都是在改变一个Matrix对象,一系列操作完毕之后,我们得到这个Matrix,然后画我们的物体,就可以了。


常用的API如下:

rotateX(float degree) 绕着x轴旋转degree个度数
rotateY(float degree) 绕着y轴旋转degree个度数
rotateZ(float degree) 绕着z轴旋转degree个度数
translate(float x,float y,float z) 平移一段距离
save()和restore() 作用跟Canvas的一样,保存原状态,操作完之后,恢复到原状态。


下面实现一个简单的图片三维翻转的效果。

Java代码 复制代码 收藏代码
  1. package chroya.demo.rotate3d;
  2. import android.content.Context;
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.graphics.Camera;
  6. import android.graphics.Canvas;
  7. import android.graphics.Matrix;
  8. import android.graphics.Paint;
  9. import android.view.MotionEvent;
  10. import android.view.View;
  11. /**
  12. * 图片三维翻转
  13. * @author chroya
  14. */
  15. public class CubeView extends View {
  16. //摄像机
  17. private Camera mCamera;
  18. //翻转用的图片
  19. private Bitmap face;
  20. private Matrix mMatrix = new Matrix();
  21. private Paint mPaint = new Paint();
  22. private int mLastMotionX, mLastMotionY;
  23. //图片的中心点坐标
  24. private int centerX, centerY;
  25. //转动的总距离,跟度数比例1:1
  26. private int deltaX, deltaY;
  27. //图片宽度高度
  28. private int bWidth, bHeight;
  29. public CubeView(Context context) {
  30. super(context);
  31. setWillNotDraw(false);
  32. mCamera = new Camera();
  33. mPaint.setAntiAlias(true);
  34. face = BitmapFactory.decodeResource(getResources(), R.drawable.x);
  35. bWidth = face.getWidth();
  36. bHeight = face.getHeight();
  37. centerX = bWidth>>1;
  38. centerY = bHeight>>1;
  39. }
  40. /**
  41. * 转动
  42. * @param degreeX
  43. * @param degreeY
  44. */
  45. void rotate(int degreeX, int degreeY) {
  46. deltaX += degreeX;
  47. deltaY += degreeY;
  48. mCamera.save();
  49. mCamera.rotateY(deltaX);
  50. mCamera.rotateX(-deltaY);
  51. mCamera.translate(0, 0, -centerX);
  52. mCamera.getMatrix(mMatrix);
  53. mCamera.restore();
  54. //以图片的中心点为旋转中心,如果不加这两句,就是以(0,0)点为旋转中心
  55. mMatrix.preTranslate(-centerX, -centerY);
  56. mMatrix.postTranslate(centerX, centerY);
  57. mCamera.save();
  58. postInvalidate();
  59. }
  60. @Override
  61. public boolean onTouchEvent(MotionEvent event) {
  62. int x = (int) event.getX();
  63. int y = (int) event.getY();
  64. switch(event.getAction()) {
  65. case MotionEvent.ACTION_DOWN:
  66. mLastMotionX = x;
  67. mLastMotionY = y;
  68. break;
  69. case MotionEvent.ACTION_MOVE:
  70. int dx = x - mLastMotionX;
  71. int dy = y - mLastMotionY;
  72. rotate(dx, dy);
  73. mLastMotionX = x;
  74. mLastMotionY = y;
  75. break;
  76. case MotionEvent.ACTION_UP:
  77. break;
  78. }
  79. return true;
  80. }
  81. @Override
  82. public void dispatchDraw(Canvas canvas) {
  83. super.dispatchDraw(canvas);
  84. canvas.drawBitmap(face, mMatrix, mPaint);
  85. }
  86. }
package chroya.demo.rotate3d; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Camera; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.view.MotionEvent; import android.view.View; /** * 图片三维翻转 * @author chroya */ public class CubeView extends View { //摄像机 private Camera mCamera; //翻转用的图片 private Bitmap face; private Matrix mMatrix = new Matrix(); private Paint mPaint = new Paint(); private int mLastMotionX, mLastMotionY; //图片的中心点坐标 private int centerX, centerY; //转动的总距离,跟度数比例1:1 private int deltaX, deltaY; //图片宽度高度 private int bWidth, bHeight; public CubeView(Context context) { super(context); setWillNotDraw(false); mCamera = new Camera(); mPaint.setAntiAlias(true); face = BitmapFactory.decodeResource(getResources(), R.drawable.x); bWidth = face.getWidth(); bHeight = face.getHeight(); centerX = bWidth>>1; centerY = bHeight>>1; } /** * 转动 * @param degreeX * @param degreeY */ void rotate(int degreeX, int degreeY) { deltaX += degreeX; deltaY += degreeY; mCamera.save(); mCamera.rotateY(deltaX); mCamera.rotateX(-deltaY); mCamera.translate(0, 0, -centerX); mCamera.getMatrix(mMatrix); mCamera.restore(); //以图片的中心点为旋转中心,如果不加这两句,就是以(0,0)点为旋转中心 mMatrix.preTranslate(-centerX, -centerY); mMatrix.postTranslate(centerX, centerY); mCamera.save(); postInvalidate(); } @Override public boolean onTouchEvent(MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); switch(event.getAction()) { case MotionEvent.ACTION_DOWN: mLastMotionX = x; mLastMotionY = y; break; case MotionEvent.ACTION_MOVE: int dx = x - mLastMotionX; int dy = y - mLastMotionY; rotate(dx, dy); mLastMotionX = x; mLastMotionY = y; break; case MotionEvent.ACTION_UP: break; } return true; } @Override public void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); canvas.drawBitmap(face, mMatrix, mPaint); } }

注释里面都写的比较清楚了。

效果如下:

可以touch来拖动图片以翻转。这个可以用来做很多事情,比如桌面的立体翻转、立体相册等等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值