3.6 三维几何体——圆环、环结、多面体
本文介绍三种三维几何体:环、环结和多面体,其中多面体使用起来非常灵活。
TorusGeometry
Torus(圆环)是一种简单的图形,看上去像是甜甜圈。程序截图如下:

创建TorusGeometry时没有必须提供的参数。下表列出的是创建这个几何体时可以指定的参数:
属性 | 是否必须 | 描述 |
radius | 否 | 设置完整圆环的尺寸,默认值是100。 |
tube | 否 | 设置管子的半径。该属性的默认值是40。 |
radialSegments | 否 | 设置沿圆环长度方向分成的段数。默认是8。 |
tubularSegments | 否 | 设置的是沿圆环宽度方向分成的段数。默认是6。 |
arc | 否 | 控制是否绘制一个完整的圆环。默认值是2*PI。 |
大部分都是你已经见过的基础属性。但是其中的arc是一个有趣的属性。通过这个属性你可以指定绘制一个完整的圆环,还是部分圆环。试验一下这个属性,你可以用它来创建出一些很有趣的网格。
完整代码略。
TorusKnotGeometry
通过TorusKnotGeometry你可以创建一个环面纽结。环面纽结是一种比较特别的结,看上去就像是一根管子绕着它自己转了几圈。程序截图如下:

修改属性p和q,你就可以创建出各种各样漂亮的几何体。p属性定义该结绕其轴多久旋转一次。p属性定义该结绕其内部旋转多少次。你不需要理解这些属性也能创建出漂亮的结(如果对细节感兴趣,Wikipedia上关于这个主题有篇很不错的文章,网址是http://en.wikipedia.org/wiki/Torus_knot)。
下表列出的是创建这个几何体时可以指定的参数:
属性 | 是否必须 | 描述 |
radius | 否 | 这个参数设置的是完整圆环的尺寸,默认值是100。 |
tube | 否 | 这个参数设置的是管子(真正的甜甜圈)的半径。该属性的默认值是40。 |
radialSegments | 否 | 这个参数设置的是沿圆环长度方向分成的段数。默认是8。 |
tubularSegments | 否 | 这个参数设置的是沿圆环宽度方向分成的段数。默认是6。 |
p | 否 | 该属性定义结的形状。默认值是2。 |
q | 否 | 该属性定义结的形状。默认值是3。 |
heightScale | 否 | 通过这个属性你可以拉伸这个环面纽结。默认值是l。 |
完整代码略。
PolyhedronGeometry
使用这个几何体,可以很容易地创建多面体。多面体是只有平面和直边的几何体。多数情况下,你不会直接使用这种几何体。Three.js提供了几种特定的多面体,你可以直接使用,不必直接设置PolyhedronGeometry的顶点和面。如果你的确想要直接使用PolyhedronGeometry,那么你不得不指定各个顶点和面。例如,要创建一个类似金字塔的多面体:
var vertices = [ 1, 0, 1, 1, 0, -1, -1, 0, -1, -1, 0, 1, 0, 1, 0 ]; var indices = [ 0, 2, 1, 3, 2, 0, 0, 1, 4, 1, 2, 4, 2, 3, 4, 3, 0, 4 ]; polyhedron = createMesh(new THREE.PolyhedronGeometry(vertices, indices, controls.radius, controls.detail));
要创建一个PolyhedronGeometry对象,我们需要传入vertices(顶点)、indices(索引)、radius(半径)和detail参数。
程序截图如下(在type下拉菜单中选择选择Custom):

当你创建多面体时,可以传入下面的四个属性:
属性 | 是否必须 | 描述 |
vertices | 是 | 定义构成多面体的顶点,每三个数字表示一个顶点的坐标。 |
indices | 是 | 指定由vertices的索引创建出的三角形,每三个数字表示一个三角形。 |
radius | 否 | 该属性指定多面体的大小,默认值是1。 |
detail | 否 | 通过这个属性可以给这个多面体添加额外的细节。如果设为1,这个多面体上的每个三角形都会分成4个小三角形。如果设为2,那么那些4个小三角形中的每一个都会继续分成4个小三角形,以此类推。 |
Three.js还提供了几个开箱即用的多面体。所有这些多面体都可以在示例中通过选择下拉菜单获得。
1.IcosahedronGeometry
通过IcosahedronGeometry(正20面体)可以创建出一个有20个相同三角形面的多面体,这些三角形面是从12个顶点创建出来的。创建这个多面体时,你要做的只是指定radius和detail,如下图所示:

2.Tetrahedron
Tetrahedron(正四面体)是最简单的多面体。这个多面体只有4个三角形面,而这些面是从4个顶点创建出来的。创建TetrahedronGeometry跟创建Three.js提供的其他多面体一样,只要指定radius和detail即可,如下图所示:

3.Octahedron
Octahedron正八面体。顾名思义,这个多面体有8个面。这些面是从6个顶点中创建出来的,如下图所示:

完整代码
<!DOCTYPE html> <html> <head> <title>示例03.06 - 三维几何体 - 多面体</title> <script src="../../../Scripts/jquery-2.1.3.min.js"></script> <script src="../../../Scripts/Threejs/three.min.js"></script> <script src="../../../Scripts/Threejs/dat.gui.min.js"></script> <script src="../../../Scripts/Threejs/stats.js"></script> <style> body { /* 将margin设置为0,overflow设置为hidden,可让浏览器显示全屏 */ margin: 0; overflow: hidden; } </style> </head> <body> <div id="Stats-output"> </div> <!-- 作为Canvas容器的div --> <div id="WebGL-output"> </div> <script type="text/javascript"> $(function () { var stats = initStats(); // 创建scene对象,用来容纳网格、相机、光源等对象 var scene = new THREE.Scene(); // 创建相机 var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = -30; camera.position.y = 40; camera.position.z = 50; camera.lookAt(new THREE.Vector3(10, 0, 0)); // 创建渲染器,并设置视口大小和清除色 var webGLRenderer = new THREE.WebGLRenderer(); webGLRenderer.setClearColor(0xEEEEEE, 1.0); webGLRenderer.setSize(window.innerWidth, window.innerHeight); webGLRenderer.shadowMapEnabled = true; $("#WebGL-output").append(webGLRenderer.domElement); // 添加多面体 var polyhedron = createMesh(new THREE.IcosahedronGeometry(10, 0)); scene.add(polyhedron); // 创建用户界面 var controls = new function () { console.log(polyhedron.children[0].geometry); this.radius = 10; this.detail = 0; this.type = 'Icosahedron'; this.redraw = function () { // 移除前面创建的多边形 scene.remove(polyhedron); // 创建一个新的多边形 switch (controls.type) { case 'Icosahedron': polyhedron = createMesh(new THREE.IcosahedronGeometry(controls.radius, controls.detail)); break; case 'Tetrahedron': polyhedron = createMesh(new THREE.TetrahedronGeometry(controls.radius, controls.detail)); break; case 'Octahedron': polyhedron = createMesh(new THREE.OctahedronGeometry(controls.radius, controls.detail)); break; case 'Custom': var vertices = [ 1, 0, 1, 1, 0, -1, -1, 0, -1, -1, 0, 1, 0, 1, 0 ]; var indices = [ 0, 2, 1, 3, 2, 0, 0, 1, 4, 1, 2, 4, 2, 3, 4, 3, 0, 4 ]; polyhedron = createMesh(new THREE.PolyhedronGeometry(vertices, indices, controls.radius, controls.detail)); break; } // 将新的多边形添加到场景中 scene.add(polyhedron); }; } var gui = new dat.GUI(); gui.add(controls, 'radius', 0, 40).step(1).onChange(controls.redraw); gui.add(controls, 'detail', 0, 3).step(1).onChange(controls.redraw); gui.add(controls, 'type', ['Icosahedron', 'Tetrahedron', 'Octahedron', 'Custom']).onChange(controls.redraw); render(); function createMesh(geom) { // 两个材质 var meshMaterial = new THREE.MeshNormalMaterial(); meshMaterial.side = THREE.DoubleSide; meshMaterial.shading = THREE.FlatShading; var wireFrameMat = new THREE.MeshBasicMaterial(); wireFrameMat.wireframe = true; // 创建一个使用组合材质的网格 var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]); return mesh; } var step = 0; function render() { stats.update(); polyhedron.rotation.y = step += 0.01; requestAnimationFrame(render); webGLRenderer.render(scene, camera); } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; $("#Stats-output").append(stats.domElement); return stats; } }); </script> </body> </html>文件下载(已下载 1808 次)
发布时间:2015/8/20 下午8:35:02 阅读次数:7603