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  阅读次数:6469

2006 - 2024,推荐分辨率 1024*768 以上,推荐浏览器 Chrome、Edge 等现代浏览器,截止 2021 年 12 月 5 日的访问次数:1872 万 9823 站长邮箱

沪 ICP 备 18037240 号-1

沪公网安备 31011002002865 号