欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

camera 3d特效 详解与进阶

程序员文章站 2024-03-21 12:09:28
...

本文转自:http://blog.csdn.net/cquwentao/article/details/51463033

1 概述

本篇主要讲解camera,这里的camera并不是照相相关的类,而是Android.graphics.Camera,这个类中封装了一个matrix,不熟悉的同学可以看前面的文章来了解。android matrix 最全方法详解与进阶(完整篇)

这里和前面的详解与进阶系列一致,我们依然是先挨个讲解camera提供的方法,然后再讲解他们的实际应用。在此之前,我们先讲一些背景知识。先来看一个坐标系:

camera 3d特效 详解与进阶

在前面的matrix中我们讲到过,其实屏幕后方是一个三维坐标系,这个坐标系的y轴正方向是朝上的,z轴是朝里面的,屏幕像一个窗口,我们看到的是窗口外面的物体投射到窗口上的二维镜像。Camera实际上就像我们的眼睛,眼睛看到的是物体投射到窗口上的图形,其实这里就有3个要素,一是物体,二是窗子,三是眼睛,也就是物体,屏幕和camera。最终呈现在用户面前的是屏幕上的图形。影响物体投射到屏幕上的效果,可以移动物体(前面讲解的matrix),也可以移动眼睛(看下面的setLocation方法解析,会有详细讲解)。通过这些不同的操作,最终使得映射在屏幕上的图形不同,然后呈现给用户的也就不同了。

其实camera就是用一种我们很好理解的方式,来简化了图形的变换操作。

2 方法解析

(1) save与

相信在前面的canvas讲解中,大家对这两个方法的名称已经很熟悉了,其实这里的这两个方法跟canvas中基本相同,也是一个保存和恢复,也是成对使用。

(2) translate

public native void translate(float x, float y, float z);

看到translate就知道是平移,这里是沿着3个轴移动物体,经过概述中我们对坐标系的讲解,我们知道了有x,y,z三个坐标轴,所以,这里的参数也是有3个,分别对应了物体在x,y,z三个轴上移动。

但是如果指定了x,y同时也指定了z,那么最终的结果就是x,y移动的距离也会受z影响。

camera 3d特效 详解与进阶

代码如下;

camera.translate(100, 0, 500);
camera.getMatrix(matrix);

canvas.translate(0,1000);
canvas.drawRect(0, 0, bw, bh, paint);
canvas.drawLine(100,0,100,1000,paint);

canvas.drawBitmap(bitmap, matrix, paint);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

左边的蓝色线条代表了x=100,这里我们方法使用的是camera.translate(100, 0, 500);本来应该移动100,但是可以看到,图片没有往右边移动这么多,这里是因为x轴的参数,引起了图片的缩放,导致了移动距离也被缩放了。

(3) rotateX

public native void rotateX(float deg)

沿着x轴旋转,这里的deg代表了度数。来看一个例子:

camera 3d特效 详解与进阶

代码如下:

camera.rotateX(180);
camera.getMatrix(matrix);

canvas.translate(0,1000);
canvas.drawRect(0, 0, bw, bh, paint);

canvas.drawBitmap(bitmap, matrix, paint);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

比较简单,就不做讲解啦。

(4) rotateY

public native void rotateY(float deg)

这个方法和上面的x基本类似,只是方向改变了一下。这里不再讲解了。

(4) rotateZ

public native void rotateZ(float deg);

这里主要是绕Z轴旋转,看一下实例图片:

camera 3d特效 详解与进阶

这里只旋转了30度,代码如下:

camera.rotateZ(30);
camera.getMatrix(matrix);

canvas.translate(0,1000);
canvas.drawRect(0, 0, bw, bh, paint);

canvas.drawBitmap(bitmap, matrix, paint);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

(4) rotate

public native void rotate(float x, float y, float z)

这个方法可以同时实现多个轴的旋转,看一个示例:

camera 3d特效 详解与进阶

代码如下:

camera.rotate(30,30,30);
camera.getMatrix(matrix);

canvas.translate(0,1000);
canvas.drawRect(0, 0, bw, bh, paint);

canvas.drawBitmap(bitmap, matrix, paint);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

(5) setLocation

 public native void setLocation(float x, float y, float z)

设置摄像机的位置。默认的值是(0,0,-8),首先来说最好理解的是x,y,将camera沿着x,y移动,图像自然往反方向移动了。

来看一个例子:

camera 3d特效 详解与进阶

可以看到,图片往左边移动了,而这里的camera是往右边移动的:

canvas.drawBitmap(bitmap, matrix, paint);

camera.setLocation(1,0, -8);
camera.getMatrix(matrix);
canvas.translate(0,700);
canvas.drawRect(0, 0, bw, bh, paint);
canvas.drawBitmap(bitmap, matrix, paint);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

y轴上和x轴基本类似,值得注意的是,这里往x方向移动的距离单位为1,但是可以看到图中移动了不少距离,这里的单位具体是多少暂时也没有搞清楚,大家使用的时候只能多多测试。

这里最难理解的是z轴上的移动,默认的是-8,也就是说是离屏幕有8个距离远,那么他的移动会有什么作用:

camera 3d特效 详解与进阶

看看上面这张图,绿色的点是camera,这里面黑线条组成了x,y,z的坐标系,其中黄色的四边形是屏幕里面的一个图形,他绕着y轴往里面旋转了30度,它的四个顶点与camera的连线,穿过了屏幕,在屏幕上形成了绿色的四边形,最后,这个绿色的四边形就呈现给了用户。可以看到,绿色的圆点camera的z坐标是-8,如果我们把他移动为z=0,那么黄色的图形将所有点都集中在了一个点上,因为camera紧贴屏幕,所以交点只有一个点,此时将什么都没有了。如果我们拉远camera,那么绿色的四边形将会变大,大家可以用周围的物体自己试试,想象一下。

看一个例子:

camera 3d特效 详解与进阶

代码如下:

camera.rotate(0,30,0);
camera.getMatrix(matrix);
canvas.translate(300,300);
canvas.drawBitmap(bitmap, matrix, paint);

camera.setLocation(0,0, -30);
camera.getMatrix(matrix);
canvas.translate(0,700);
canvas.drawRect(0, 0, bw, bh, paint);
canvas.drawBitmap(bitmap, matrix, paint);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这里将camera拉远了到-30,不是默认的-8,刚刚我们也说了,随着camera越来越远,图形会越来越接近未旋转的样子,也就越来越大。这和旋转后的图形与camera连线在屏幕上的投影有关系。所以z轴的移动,不会影响到平移等操作,只会影响绕x,y轴的旋转。

(6) getMatrix

public void getMatrix(Matrix matrix)

这个方法在前面讲解的示例中,都用到了,这里主要是获取变换之后的matrix。就不再详细讲解了。

(7) applyToCanvas

public void applyToCanvas(Canvas canvas)

将当前的矩阵应用到canvas中,其实最终调用的是canvas.concat(mMatrix)。

例如选择了canvas,其实绘制上去的图形也就跟着旋转了:

camera 3d特效 详解与进阶

代码如下:

camera.rotate(0,30,0);
canvas.save();
camera.applyToCanvas(canvas);
camera.getMatrix(matrix);
canvas.drawBitmap(bitmap, new Matrix(), paint);
canvas.restore();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

可以看到这里应用到canvas上以后,绘制bitmap的时候并没有对bitmap做其他处理,最终也是一个旋转过的图片。