threejs学习day3:几何形状

Posted 简数

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了threejs学习day3:几何形状相关的知识,希望对你有一定的参考价值。

几何形状(Geometry)最主要的功能是储存了一个物体的顶点信息。WebGL需要程序员指定每个顶点的位置,而在Three.js中,可以通过指定一些特征来创建几何形状,例如使用半径创建一个球体,从而省去程序员一个个指定顶点的工作量。

本节将分别介绍立方体、平面、球体、圆柱体、四面体、八面体等几何形状,以及以三维文字作为几何形状的方法。本节还会介绍通过手动定义顶点位置和面片信息组成几何形状。

立方体


虽然这一形状的名字叫立方体(CubeGeometry),但它其实是长方体,也就是长宽高可以设置为不同的值。其构造函数是:

THREE.CubeGeometry(width, height, depth, widthSegments, heightSegments, depthSegments)

这里,width是x方向上的长度;height是y方向上的长度;depth是z方向上的长度;后三个参数分别是在三个方向上的分段数,如widthSegments3的话,代表x方向上水平分为三份。一般情况下不需要分段的话,可以不设置后三个参数,后三个参数的缺省值为1。其他几何形状中的分段也是类似的,下面不做说明。

长宽高

创建立方体直观简单,如:new THREE.CubeGeometry(1, 2, 3);可以创建一个x方向长度为1,y方向长度为2,z方向长度为3的立方体。

为了更好地表现参数效果,我们在场景中用长度为1的红、绿、蓝线段分别表示x、y、z三个轴。在设置材质,并添加到场景之后(具体方法参见第4章及第5章)的效果是:

物体的默认位置是原点,对于立方体而言,是其几何中心在原点的位置。

分段

而在设置了分段new THREE.CubeGeometry(1, 2, 3, 2, 2, 3)后,效果如下:

threejs学习day3:几何形状

注意这个分段是对六个面进行分段,而不是对立方体的体素分段,因此在立方体的中间是不分段的,只有六个侧面被分段。

球体


球体(SphereGeometry)的构造函数是:

THREE.SphereGeometry(radius, segmentsWidth, segmentsHeight, phiStart, phiLength, thetaStart, thetaLength)

其中,radius是半径;segmentsWidth表示经度上的切片数;segmentsHeight表示纬度上的切片数;phiStart表示经度开始的弧度;phiLength表示经度跨过的弧度;thetaStart表示纬度开始的弧度;thetaLength表示纬度跨过的弧度。

分段

首先,我们来理解下segmentsWidthsegmentsHeight。使用var sphere = new THREE.SphereGeometry(3, 8, 6)可以创建一个半径为3,经度划分成8份,纬度划分成6份的球体,如下图所示。

threejs学习day3:几何形状

segmentsWidth相当于经度被切成了几瓣,而segmentsHeight相当于纬度被切成了几层。因为在图形底层的实现中,并没有曲线的概念,曲线都是由多个折线近似构成的。对于球体而言,当这两个值较大的时候,形成的多面体就可以近似看做是球体了。

new THREE.SphereGeometry(3, 8, 6)的效果:

threejs学习day3:几何形状

new THREE.SphereGeometry(3, 18, 12)的效果:

threejs学习day3:几何形状

经度弧度

new THREE.SphereGeometry(3, 8, 6, Math.PI / 6, Math.PI / 3)表示起始经度为Math.PI / 6,经度跨度为Math.PI / 3。效果如下:

threejs学习day3:几何形状

需要注意的是,这里segmentsWidth8意味着对于经度从Math.PI / 6跨过Math.PI / 3的区域内划分为8块,而不是整个球体的经度划分成8块后再判断在此经度范围内的部分。

纬度弧度

理解了经度之后,纬度可以同理理解。new THREE.SphereGeometry(3, 8, 6, 0, Math.PI * 2, Math.PI / 6, Math.PI / 3)意味着纬度从Math.PI / 6跨过Math.PI / 3。效果如下:

threejs学习day3:几何形状

我们再来看一个经度纬度都改变了起始位置和跨度的例子:new THREE.SphereGeometry(3, 8, 6, Math.PI / 2, Math.PI, Math.PI / 6, Math.PI / 2)的效果为:

threejs学习day3:几何形状

文字形状

文字形状(TextGeometry)可以用来创建三维的文字形状。

下载使用


使用文字形状需要下载和引用额外的字体库,具体参见Three.js GitHub说明。

这里,我们以helvetiker字体为例。我们在Three.js GitHub master/examples/fonts目录下,下载helvetiker_regular.typeface.json文件放在你的目录下,然后用以下方法加载:

var loader = new THREE.FontLoader();
loader.load('../lib/helvetiker_regular.typeface.json', function(font) {
    var mesh = new THREE.Mesh(new THREE.TextGeometry('Hello', {
        font: font,
        size: 1,
        height: 1
    }), material);
    scene.add(mesh);

    // render
    renderer.render(scene, camera);
});

参数介绍


创建文字形状的流程和之前介绍的基本几何形状是类似的,其构造函数是:

THREE.TextGeometry(text, parameters)

其中,text是文字字符串,parameters是以下参数组成的对象:

  • size:字号大小,一般为大写字母的高度

  • height:文字的厚度

  • curveSegments:弧线分段数,使得文字的曲线更加光滑

  • font:字体,默认是'helvetiker',需对应引用的字体文件

  • weight:值为'normal''bold',表示是否加粗

  • style:值为'normal''italics',表示是否斜体

  • bevelEnabled:布尔值,是否使用倒角,意为在边缘处斜切

  • bevelThickness:倒角厚度

  • bevelSize:倒角宽度

实例说明

创建一个三维文字:new THREE.TextGeometry('Hello', {size: 1, height: 1}),其效果为:

threejs学习day3:几何形状

改变材质和光照之后就能达到这样的效果:

threejs学习day3:几何形状

自定义形状

对于Three.js没有提供的形状,可以提供自定义形状来创建。

由于自定义形状需要手动指定每个顶点位置,以及顶点连接情况,如果该形状非常复杂,程序员的计算量就会比较大。在这种情况下,建议在3ds Max之类的建模软件中创建模型,然后使用Three.js导入到场景中,这样会更高效方便。

自定义形状使用的是Geometry类,它是其他如CubeGeometry、SphereGeometry等几何形状的父类,其构造函数是:

THREE.Geometry()

我们以创建一个梯台为例,首先,初始化一个几何形状,然后设置顶点位置以及顶点连接情况。

// 初始化几何形状
var geometry = new THREE.Geometry();

// 设置顶点位置
// 顶部4顶点
geometry.vertices.push(new THREE.Vector3(-1, 2, -1));
geometry.vertices.push(new THREE.Vector3(1, 2, -1));
geometry.vertices.push(new THREE.Vector3(1, 2, 1));
geometry.vertices.push(new THREE.Vector3(-1, 2, 1));
// 底部4顶点
geometry.vertices.push(new THREE.Vector3(-2, 0, -2));
geometry.vertices.push(new THREE.Vector3(2, 0, -2));
geometry.vertices.push(new THREE.Vector3(2, 0, 2));
geometry.vertices.push(new THREE.Vector3(-2, 0, 2));

// 设置顶点连接情况
// 顶面
geometry.faces.push(new THREE.Face3(0, 1, 3));
geometry.faces.push(new THREE.Face3(1, 2, 3));
// 底面
geometry.faces.push(new THREE.Face3(4, 5, 6));
geometry.faces.push(new THREE.Face3(5, 6, 7));
// 四个侧面
geometry.faces.push(new THREE.Face3(1, 5, 6));
geometry.faces.push(new THREE.Face3(6, 2, 1));
geometry.faces.push(new THREE.Face3(2, 6, 7));
geometry.faces.push(new THREE.Face3(7, 3, 2));
geometry.faces.push(new THREE.Face3(3, 7, 0));
geometry.faces.push(new THREE.Face3(7, 4, 0));
geometry.faces.push(new THREE.Face3(0, 4, 5));
geometry.faces.push(new THREE.Face3(0, 5, 1));

效果是:

需要注意的是,new THREE.Vector3(-1, 2, -1)创建一个矢量,作为顶点位置追加到geometry.vertices数组中。

而由new THREE.Face3(0, 1, 3)创建一个三个顶点组成的面片,追加到geometry.faces数组中。三个参数分别是四个顶点在geometry.vertices中的序号。

在之前版本的Three.js中,可以使用Face4创建四边形,如今已经弃用。由于四个点未必共面,所以使用三角形永远是最安全的方法。

以上是关于threejs学习day3:几何形状的主要内容,如果未能解决你的问题,请参考以下文章

threejs学习day6:外部模型

关于Three.js基本几何形状正与四面体正八面体正二十面体学习

图形细分 —— threejs

threejs+d3js 绘制3D动态数据图

ThreeJS——3D场景中插入多个几何体

OpenCV中几何形状识别与测量