学习threejs,使用多面体(IcosahedronGeometry、TetrahedronGeometry、OctahedronGeometry等)

发布于:2025-03-28 ⋅ 阅读:(30) ⋅ 点赞:(0)

👨‍⚕️ 主页: gis分享者
👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨‍⚕️ 收录于专栏:threejs gis工程师



一、🍀前言

本文详细介绍如何基于threejs在三维场景中使用多面体几何对象IcosahedronGeometry二十面体、TetrahedronGeometry四面体、OctahedronGeometry八面体、DodecahedronGeometry十二面体、PolyhedronGeometry自定义多面体,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️THREE.PolyhedronGeometry 自定义多面体

THREE.PolyhedronGeometry多面体在三维空间中具有一些平面的立体图形。这个类将一个顶点数组投射到一个球面上,之后将它们细分为所需的细节级别。 这个类由DodecahedronGeometry、IcosahedronGeometry、OctahedronGeometry和TetrahedronGeometry 所使用,以生成它们各自的几何结构。

1.1.1 ☘️代码示例

代码示例

const verticesOfCube = [
    -1,-1,-1,    1,-1,-1,    1, 1,-1,    -1, 1,-1,
    -1,-1, 1,    1,-1, 1,    1, 1, 1,    -1, 1, 1,
];

const indicesOfFaces = [
    2,1,0,    0,3,2,
    0,4,7,    7,3,0,
    0,1,5,    5,4,0,
    1,2,6,    6,5,1,
    2,3,7,    7,6,2,
    4,5,6,    6,7,4
];

const geometry = new THREE.PolyhedronGeometry( verticesOfCube, indicesOfFaces, 6, 2 );

1.1.2 ☘️构造函数

PolyhedronGeometry(vertices : Array, indices
vertices — 一个顶点Array(数组):[1,1,1, -1,-1,-1, … ]。
indices — 一个构成面的索引Array(数组), [0,1,2, 2,3,0, … ]。
radius — Float - 最终形状的半径。
detail — Integer - 将对这个几何体细分多少个级别。细节越多,形状就越平滑。

1.1.3 ☘️属性

共有属性请参见其基类BufferGeometry

.parameters : Object
一个包含着构造函数中每个参数的对象。在对象实例化之后,对该属性的任何修改都不会改变这个几何体。

1.1.4 ☘️方法

共有方法请参见其基类BufferGeometry

1.2 ☘️THREE.IcosahedronGeometry 二十面体

THREE.IcosahedronGeometry一个用于生成二十面体的类。

1.2.1 ☘️构造函数

IcosahedronGeometry(radius : Float, detail : Integer)
radius — 二十面体的半径,默认为1。
detail — 默认值为0。将这个值设为一个大于0的数将会为它增加一些顶点,使其不再是一个二十面体。当这个值大于1的时候,实际上它将变成一个球体。

1.2.2 ☘️属性

共有属性请参见其基类PolyhedronGeometry。

.parameters : Object
一个包含着构造函数中每个参数的对象。在对象实例化之后,对该属性的任何修改都不会改变这个几何体。

1.2.3 ☘️方法

共有方法请参见其基类PolyhedronGeometry。

1.3 ☘️THREE.TetrahedronGeometry 四面体

THREE.TetrahedronGeometry一个用于生成四面几何体的类。

1.3.1 ☘️构造函数

TetrahedronGeometry(radius : Float, detail : Integer)
radius — 四面体的半径,默认值为1。
detail — 默认值为0。将这个值设为一个大于0的数将会为它增加一些顶点,使其不再是一个四面体。

1.3.2 ☘️属性

共有属性请参见其基类PolyhedronGeometry。

.parameters : Object
一个包含着构造函数中每个参数的对象。在对象实例化之后,对该属性的任何修改都不会改变这个几何体。

1.3.3 ☘️方法

共有方法请参见其基类PolyhedronGeometry。

1.4 ☘️THREE.OctahedronGeometry 八面体

THREE.OctahedronGeometry一个用于创建八面体的类。

1.4.1 ☘️构造函数

OctahedronGeometry(radius : Float, detail : Integer)
radius — 八面体的半径,默认值为1。
detail — 默认值为0,将这个值设为一个大于0的数将会为它增加一些顶点,使其不再是一个八面体。

1.4.2 ☘️属性

共有属性请参见其基类PolyhedronGeometry。

.parameters : Object
一个包含着构造函数中每个参数的对象。在对象实例化之后,对该属性的任何修改都不会改变这个几何体。

1.4.3 ☘️方法

共有方法请参见其基类PolyhedronGeometry。

1.5 ☘️THREE.DodecahedronGeometry 八面体

THREE.DodecahedronGeometry一个用于创建十二面几何体的类。

1.5.1 ☘️构造函数

DodecahedronGeometry(radius : Float, detail : Integer)
radius — 十二面体的半径,默认值为1。
detail — 默认值为0。将这个值设为一个大于0的数将会为它增加一些顶点,使其不再是一个十二面体。

1.5.2 ☘️属性

共有属性请参见其基类PolyhedronGeometry。

.parameters : Object
一个包含着构造函数中每个参数的对象。在对象实例化之后,对该属性的任何修改都不会改变这个几何体。

1.5.3 ☘️方法

共有方法请参见其基类PolyhedronGeometry。

二、🍀使用多面体几何对象IcosahedronGeometry二十面体、TetrahedronGeometry四面体、OctahedronGeometry八面体、DodecahedronGeometry十二面体、PolyhedronGeometry自定义多面体

1. ☘️实现思路

  • 1、初始化renderer渲染器。
  • 2、初始化Scene三维场景scene。
  • 3、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt。
  • 4、加载几何模型:定义controls方法,初始化gui多面体控制项,根据type创建多面体对象。创建createMesh方法(参数为geom几何体对象),创建THREE.MeshNormalMaterial法向量材质meshMaterial,创建THREE.MeshBasicMaterial基础材质wireFrameMat,传入参数geom、meshMaterial、wireFrameMat调用createMultiMaterialObject创建网格对象mesh。调用createMesh(new THREE.IcosahedronGeometry(10, 0))创建二十面体网格对象polyhedron,scene场景添加polyhedron。定义render方法,实现polyhedron的旋转动画,调用render方法。具体代码参考下面代码样例。
  • 5、加入gui控制,控制多面体的了类型type、半径radius和顶点detail。加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html>
<html>
<head>
    <title>学习threejs,使用多面体(IcosahedronGeometry、TetrahedronGeometry、OctahedronGeometry等)</title>
    <script type="text/javascript" src="../libs/three.js"></script>
    <script type="text/javascript" src="../libs/stats.js"></script>
    <script type="text/javascript" src="../libs/dat.gui.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<div id="Stats-output">
</div>
<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Js 代码块 -->
<script type="text/javascript">

    // 初始化
    function init() {

        var stats = initStats();

        // 创建三维场景scene
        var scene = new THREE.Scene();

        // 创建相机camera
        var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

        // 创建渲染器webGLRenderer,设置webGLRenderer的颜色和大小
        var webGLRenderer = new THREE.WebGLRenderer();
        webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
        webGLRenderer.setSize(window.innerWidth, window.innerHeight);
        webGLRenderer.shadowMapEnabled = true;

        var polyhedron = createMesh(new THREE.IcosahedronGeometry(10, 0));
        // 添加二十面体网格对象
        scene.add(polyhedron);

        // 设置相机位置和方向
        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 50;
        camera.lookAt(new THREE.Vector3(10, 0, 0));

        // 渲染器webGLRenderer绑定html要素
        document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);

        var step = 0;


        var controls = new function () {
            // 初始化gui控制项,创建多面体对象
            this.radius = 10;
            this.detail = 0;
            this.type = 'Icosahedron';


            this.redraw = function () {
                // remove the old plane
                scene.remove(polyhedron);
                // create a new one

                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 'Dodecahedron':
                        polyhedron = createMesh(new THREE.DodecahedronGeometry(controls.radius, controls.detail));
                        break;
                    case 'Custom':
                        var vertices = [
                            1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1
                        ];

                        var indices = [
                            2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1
                        ];

                        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', 'Dodecahedron', 'Custom']).onChange(controls.redraw);


        render();

        function createMesh(geom) {

            var meshMaterial = new THREE.MeshNormalMaterial();
            meshMaterial.side = THREE.DoubleSide;
            var wireFrameMat = new THREE.MeshBasicMaterial();
            wireFrameMat.wireframe = true;
            var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]);

            return mesh;
        }

        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);

            stats.domElement.style.position = 'absolute';
            stats.domElement.style.left = '0px';
            stats.domElement.style.top = '0px';

            document.getElementById("Stats-output").appendChild(stats.domElement);

            return stats;
        }
    }
    window.onload = init;
</script>
</body>
</html>

效果如下:
blog.csdnimg.cn/direct/82ef60de80ca4834a237dbad7eeb48cd.gif)