三维世界中的坐标系

上篇文章中介绍了threejs中几个基本概念,例如场景、相机、渲染器以及组件等,并通过一个简单的案例向小伙伴展示了这些东西的用法,本文来看看threejs中的坐标体系。

本文是threejs系列的第二篇,阅读前面的文章有助于更好的理解本文:


1.一个简单的案例,理解threejs中几个基本概念


坐标体系

首先,threejs中坐标体系是右手坐标系,如下图:

640?wx_fmt=png

在此基础上,坐标体系分为世界坐标和本地坐标,相机默认位于世界坐标体系的(0,0,0)点,本地坐标则是一个组件内部的坐标。如下图,每个组件内部都会有一个坐标体系,这个就是本地坐标:

640?wx_fmt=png

默认位置

按理说,场景是不需要坐标这个概念的,其他的组件和相机是有坐标的,在上文的案例中,读者可以在浏览器控制台打印出所有的坐标:

640?wx_fmt=png

可以看到,相机的坐标是(0,0,5),其他的坐标则都是(0,0,0),相机默认坐标也是(0,0,0),只是由于我们在代码中配置了z轴坐标为5,不知读者是否还记得上文中如下一行代码:

camera.position.z = 5;

经过上面的分析,我们直到,相机和组件默认都是在世界坐标的原点。

案例演示

还是上文的案例,接下来,我再添加一个坐标系到场景中,如下:

var scene = new THREE.Scene();	
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);	
var render = new THREE.WebGLRenderer();	
render.setClearColor("#FFFFFF");	
render.setSize(window.innerWidth, window.innerHeight);	
document.body.appendChild(render.domElement);	
var geometry = new THREE.CubeGeometry(1,1,1);	
var material = new THREE.MeshBasicMaterial({color: 0xFFB6C1});	
var cube = new THREE.Mesh(geometry, material);	
scene.add(cube);	
var axesHelper = new THREE.AxesHelper(5);	
scene.add(axesHelper);	
camera.position.z = 5;	
function showCube() {	
    requestAnimationFrame(showCube)	
    cube.rotation.x += 0.01;	
    cube.rotation.y += 0.01;	
    cube.rotation.z += 0.01;	
    render.render(scene, camera);	
}	
showCube()

和上文相比,这里主要是多了AxesHelper,这是一个坐标系,我向场景中添加了这个坐标系:

640?wx_fmt=gif

不过读者看到,这里红色是x轴,绿色是y轴,好像没有看到z轴?这是因为z轴垂直于屏幕,而相机目前的位置是(0,0,5),因此看不到z轴,将相机在x轴方向上移动1个单位,即添加如下代码:

camera.position.x = 1;

此时页面展示结果如下:

640?wx_fmt=gif

当然这样看起来三维的效果还是不太明显,那么可以将相机向上太高一点,即相机的y轴移动一个单位,此时,拍摄到的图像会相应的向下移动一个单位,为了使组件看起来依然在原点,这个时候需要调整下相机的方向,相机本来是查看正前方事物,现在让它低头看(0,0,0)点,就像你本来站着眺望远处的高山,手上的手机在视野的下方,现在让你低头45度看看手上的手机,此时手机就在视野的正中心,最终修改相机的代码如下:

camera.position.z = 5;	
camera.position.x = 1;	
camera.position.y = 1;	
camera.lookAt(0, 0, 0);

其中lookAt表示一个方向,即相机对着哪个点看,如下:

640?wx_fmt=gif

不过此时的旋转只有立方体在旋转,坐标轴未旋转,要想使坐标轴旋转,修改showCube方法,如下:

function showCube() {	
    requestAnimationFrame(showCube)	
    cube.rotation.x += 0.01;	
    cube.rotation.y += 0.01;	
    cube.rotation.z += 0.01;	
    axesHelper.rotation.x += 0.01;	
    axesHelper.rotation.y += 0.01;	
    axesHelper.rotation.z += 0.01;	
    render.render(scene, camera);	
}

修改之后,旋转效果如下:

640?wx_fmt=gif

另外,也可以将这两个组件放到一个Object3D对象中,作为一个整体旋转,如下:

var scene = new THREE.Scene();	
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);	
var render = new THREE.WebGLRenderer({	
    antialias: true	
});	
var obj = new THREE.Object3D();	
render.setClearColor("#FFFFFF");	
render.setSize(window.innerWidth, window.innerHeight);	
document.body.appendChild(render.domElement);	
var geometry = new THREE.CubeGeometry(1, 1, 1);	
var material = new THREE.MeshBasicMaterial({color: 0xFFB6C1});	
var cube = new THREE.Mesh(geometry, material);	
obj.add(cube);	
var axesHelper = new THREE.AxesHelper(5);	
obj.add(axesHelper);	
scene.add(obj);	
camera.position.z = 5;	
camera.position.x = 1;	
camera.position.y = 1;	
camera.lookAt(0, 0, 0);	
function showCube() {	
    requestAnimationFrame(showCube)	
    obj.rotation.x += 0.01;	
    obj.rotation.y += 0.01;	
    obj.rotation.z += 0.01;	
    render.render(scene, camera);	
}	
showCube()

可以看到,立方体和坐标轴都是添加到Object3D中,而Object3D则添加到场景中,旋转时候,只需要Object3D旋转即可,效果与上图类似,这里不再赘述,另外,在创建WebGLRenderer渲染器时,还增加了antialias参数,表示抗锯齿。

好了,本文的介绍就说到这里,有问题欢迎留言讨论。

本文案例:https://github.com/lenve/threejsDemo

▼往期精彩回顾▼ Redis教程 SpringCloud教程 Git教程 MongoDB教程 SpringBoot+Vue前后端分离开源项目-微人事 SpringBoot+Vue前后端分离开源项目-V部落

640?wx_fmt=png

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页