• Three.js开发指南---学习使用几何体(第五章)


    一 基础几何体

      1 二维图形:二维图形都是基于x和y轴构建的,即展示的形式就是他们都是“直立”的,如果希望这些二维图形躺下,则需要将几何体沿着x轴向后旋转1/4圈

    mesh.rotation.x=-Math.PI/2;

      1.1 PlaneGeometry:平面几何体 new THREE.PlaneGeometry(width,height,widthSegments,heightSegments)

    <!DOCTYPE html>
    
    <html>
    
    <head>
        <title>Example 05.01 - Basic 2D geometries - Plane</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 {
                /* set margin to 0 and overflow to hidden, to go fullscreen */
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
    
    <div id="Stats-output">
    </div>
    <!-- Div which will hold the Output -->
    <div id="WebGL-output">
    </div>
    
    <!-- Javascript code that runs our Three.js examples -->
    <script type="text/javascript">
    
        // once everything is loaded, we run our Three.js stuff.
        function init() {
    
            //var stats = initStats();
    
            // create a scene, that will hold all our elements such as objects, cameras and lights.
            var scene = new THREE.Scene();
    
            // create a camera, which defines where we're looking at.
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    
            // create a render and set the size
            var webGLRenderer = new THREE.WebGLRenderer();
            webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
            webGLRenderer.setSize(window.innerWidth, window.innerHeight);
            webGLRenderer.shadowMapEnabled = true;
            
            //宽 高,宽度分为几段,长度分为几段
            var plane = createMesh(new THREE.PlaneGeometry(10, 14, 4, 4));
            // add the sphere to the scene
            scene.add(plane);
    
            // position and point the camera to the center of the scene
            camera.position.x = -20;
            camera.position.y = 30;
            camera.position.z = 40;
            camera.lookAt(new THREE.Vector3(10, 0, 0));
    
    
            // add spotlight for the shadows
            var spotLight = new THREE.SpotLight(0xffffff);
            spotLight.position.set(-40, 60, -10);
            scene.add(spotLight);
    
            // add the output of the renderer to the html element
            document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
    
            // call the render function
            var step = 0;
    
    
            // setup the control gui
            var controls = new function () {
                // we need the first child, since it's a multimaterial
    
                //初始控制器的宽和高展示的是上面我们new THREE.Plane的宽和高
                //所以我们使用对象plane来获取其宽和高以及宽度的段数和高度的段数
                this.width = plane.children[0].geometry.parameters.width;
                this.height = plane.children[0].geometry.parameters.height;
    
                this.widthSegments = plane.children[0].geometry.parameters.widthSegments;
                this.heightSegments = plane.children[0].geometry.parameters.heightSegments;
    
                this.redraw = function () {
                    // remove the old plane
                    scene.remove(plane);
                    // create a new one
                    plane = createMesh(new THREE.PlaneGeometry(controls.width, controls.height, Math.round(controls.widthSegments), Math.round(controls.heightSegments)));
                    // add it to the scene.
                    scene.add(plane);
                };
            };
    
            var gui = new dat.GUI();
            gui.add(controls, 'width', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'height', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'widthSegments', 0, 10).onChange(controls.redraw);
            gui.add(controls, 'heightSegments', 0, 10).onChange(controls.redraw);
            render();
    
            function createMesh(geom) {
    
                // 生成一个法向量材质
                var meshMaterial = new THREE.MeshNormalMaterial();
                //几何体的两面都应用该材质
                meshMaterial.side = THREE.DoubleSide;
                //生成一个基础材质,即赋予几何体一种简单的颜色或者线框
                var wireFrameMat = new THREE.MeshBasicMaterial();
                //看来基础材质在此处的作用是线框
                wireFrameMat.wireframe = true;
    
                // create a multimaterial
                //一种几何体应用多种材质THREE.SceneUtils.createMultiMaterialObject
                var plane = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]);
    
                return plane;
            }
    
            function render() {
                //stats.update();
    
                plane.rotation.y = step += 0.01;
    
                // render using requestAnimationFrame
                requestAnimationFrame(render);
                webGLRenderer.render(scene, camera);
            }
    
            
        }
        window.onload = init;
    </script>
    </body>
    </html>

    1.2 CircleGeometry:二维圆/部分圆:new THREE.CircleGeometry(radius,segment,thetaStart开始角度,thetaLength角度)

    <!DOCTYPE html>
    
    <html>
    
    <head>
        <title>Example 05.02 - Basic 2D geometries - Circle</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 {
                /* set margin to 0 and overflow to hidden, to go fullscreen */
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
    
    <div id="Stats-output">
    </div>
    <!-- Div which will hold the Output -->
    <div id="WebGL-output">
    </div>
    
    <!-- Javascript code that runs our Three.js examples -->
    <script type="text/javascript">
    
        // once everything is loaded, we run our Three.js stuff.
        function init() {
    
            var stats = initStats();
    
            // create a scene, that will hold all our elements such as objects, cameras and lights.
            var scene = new THREE.Scene();
    
            // create a camera, which defines where we're looking at.
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    
            // create a render and set the size
            var webGLRenderer = new THREE.WebGLRenderer();
            webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
            webGLRenderer.setSize(window.innerWidth, window.innerHeight);
            webGLRenderer.shadowMapEnabled = true;
    
            var circle = createMesh(new THREE.CircleGeometry(4, 10, 0, Math.PI * 2));
            // add the sphere to the scene
            scene.add(circle);
    
            // position and point the camera to the center of the scene
            camera.position.x = -20;
            camera.position.y = 30;
            camera.position.z = 40;
            camera.lookAt(new THREE.Vector3(10, 0, 0));
    
    
            // add spotlight for the shadows
            var spotLight = new THREE.SpotLight(0xffffff);
            spotLight.position.set(-40, 60, -10);
            scene.add(spotLight);
    
            // add the output of the renderer to the html element
            document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
    
            // call the render function
            var step = 0;
    
    
            // setup the control gui
            var controls = new function () {
                // we need the first child, since it's a multimaterial
    
    
                //console.log(circle.children[0].geometry);
                this.radius =circle.children[0].geometry.parameters.radius;
    
                this.thetaStart =circle.children[0].geometry.parameters.thetaStart;
                this.thetaLength =circle.children[0].geometry.parameters.thetaLength;
                this.segments =circle.children[0].geometry.parameters.segments;
    
                this.redraw = function () {
                    // remove the old plane
                    scene.remove(circle);
                    // create a new one
                    circle = createMesh(new THREE.CircleGeometry(controls.radius, controls.segments, controls.thetaStart, controls.thetaLength));
                    // add it to the scene.
                    
                    scene.add(circle);
                };
            };
    
            var gui = new dat.GUI();
            gui.add(controls, 'radius', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'segments', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'thetaStart', 0, 2 * Math.PI).onChange(controls.redraw);
            gui.add(controls, 'thetaLength', 0, 2 * Math.PI).onChange(controls.redraw);
            render();
    
            function createMesh(geom) {
    
                // assign two materials
                var meshMaterial = new THREE.MeshNormalMaterial();
                meshMaterial.side = THREE.DoubleSide;
                var wireFrameMat = new THREE.MeshBasicMaterial();
                wireFrameMat.wireframe = true;
    
                // create a multimaterial
                var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]);
                
                //将该二维圆形“放倒”
                mesh.rotation.x=-Math.PI/2
                return mesh;
            }
    
            function render() {
                stats.update();
    
                circle.rotation.y = step += 0.01;
    
                // render using requestAnimationFrame
                requestAnimationFrame(render);
                webGLRenderer.render(scene, camera);
            }
    
            function initStats() {
    
                var stats = new Stats();
                stats.setMode(0); // 0: fps, 1: ms
    
                // Align top-left
                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>

      1.3 塑形平面:ShapeGeometry

       使用ShapeGeometry定制图形,必须使用shape的绘制函数,下面我们先介绍一下绘制函数

    Shape对象(注意与ShapGeometry对象的区别)的绘图函数

    函数名称 描述
    moveTo 将绘图点移动到某个位置
    lineTo /从当前位置绘制一条直线到指定的x,y处
    quadraticCurveTo(acPx,acPy) 二次曲线
    bezierCurveTo(acPx1,acPy1,acPx2,acPy2,x,y) 贝塞尔曲线
     splineThru(数组集合)  沿着所给定的点,绘制一条光滑的曲线,参数是一个THREE.Vector2的数组

     arc(ax,ay,aRdius,aStartAngle,aEndAngle,aClockwise)

     ax,ay用来指定圆心与当前位置之间的偏移量,

    aRadius半径,

    aStartAngle,aEndAngle开始与结束的弧长,

    以及aClockwise顺/逆时针

     makeGeometry 该函数从Shape对象返回一个ShapeGeometry对象
      createPointsGeometry(divisions)

    将图形转换为一个点集,参数为返回点的数量,该值越高,返回的点越多,再次绘制图形时曲线越光滑

    参数divisions会分别应用到路径的每一个部分

       createSpacedPointsGeometry(divisions)  与createPointsGeometry函数功能相同,但是该方法的参数会一次性的应用到整个路径上
    <!DOCTYPE html>
    
    <html>
    
    <head>
        <title>Example 05.03 - Basic 2D geometries - Shape</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 {
                /* set margin to 0 and overflow to hidden, to go fullscreen */
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
    
    <div id="Stats-output">
    </div>
    <!-- Div which will hold the Output -->
    <div id="WebGL-output">
    </div>
    
    <!-- Javascript code that runs our Three.js examples -->
    <script type="text/javascript">
    
        // once everything is loaded, we run our Three.js stuff.
        function init() {
    
            // create a scene, that will hold all our elements such as objects, cameras and lights.
            var scene = new THREE.Scene();
    
            // create a camera, which defines where we're looking at.
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    
            // create a render and set the size
            var webGLRenderer = new THREE.WebGLRenderer();
            webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
            webGLRenderer.setSize(window.innerWidth, window.innerHeight);
            webGLRenderer.shadowMapEnabled = true;
            var shape=drawShape();//此处返回的是Shape对象
            var shapeGeo=new THREE.ShapeGeometry(shape);//Shape对象是作为参数传递给ShapeGeometry对象的构造函数的
            var shapeMesh = createMesh(shapeGeo);//几何体与材质相结合生成一个网格
            // add the sphere to the scene
            scene.add(shapeMesh);//将网格追加到场景中
    
            // position and point the camera to the center of the scene
            camera.position.x = -30;
            camera.position.y = 70;
            camera.position.z = 70;
            camera.lookAt(new THREE.Vector3(10, 0, 0));
    
    
            // add spotlight for the shadows
            var spotLight = new THREE.SpotLight(0xffffff);
            spotLight.position.set(-40, 60, -10);
            scene.add(spotLight);
    
            // add the output of the renderer to the html element
            document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
    
            // call the render function
            var step = 0;
    
    
            // setup the control gui
            var controls = new function () {
    
                this.asGeom = function () {
                    // remove the old plane
                    scene.remove(shapeMesh);
                    // create a new one
          //注意shape,shapGeometry的关系
    var shape=drawShape(); var shapeGeo=new THREE.ShapeGeometry(shape); shapeMesh = createMesh(shapeGeo); // add it to the scene. scene.add(shapeMesh); }; this.asPoints = function () { // remove the old plane scene.remove(shapeMesh); // create a new one var shapeMesh = createLine(drawShape(), false); // add it to the scene. scene.add(shapeMesh); }; this.asSpacedPoints = function () { // remove the old plane scene.remove(shapeMesh); // create a new one shapeMesh = createLine(drawShape(), true); // add it to the scene. scene.add(shapeMesh); }; }; var gui = new dat.GUI(); gui.add(controls, 'asGeom'); gui.add(controls, 'asPoints'); gui.add(controls, 'asSpacedPoints'); render(); function drawShape() { // create a basic shape var shape = new THREE.Shape(); // startpoint开始的点 shape.moveTo(10, 10); // straight line upwards 沿着开始点画直线 shape.lineTo(10, 40); // the top of the figure, curve to the right 绘制贝塞尔曲线 shape.bezierCurveTo(15, 25, 25, 25, 30, 40); // spline back down 沿着所提供的坐标集合绘制一条光滑的曲线,起始点是当前所在的位置 shape.splineThru( [new THREE.Vector2(32, 30), new THREE.Vector2(28, 20), new THREE.Vector2(30, 10), ]); // curve at the bottom,绘制二次曲线 shape.quadraticCurveTo(20, 15, 10, 10); // add 'eye' hole one var hole1 = new THREE.Path(); //绘制圆弧 hole1.absellipse(16, 24, 2, 3, 0, Math.PI * 2, true); shape.holes.push(hole1); // add 'eye hole 2' var hole2 = new THREE.Path(); hole2.absellipse(23, 24, 2, 3, 0, Math.PI * 2, true); shape.holes.push(hole2); // add 'mouth' var hole3 = new THREE.Path(); hole3.absarc(20, 16, 2, 0, Math.PI, true); shape.holes.push(hole3); //Shape对象的makeGeometry方法,用于返回一个几何体 console.log(shape.makeGeometry()); return shape; } function createMesh(geom) { //console.log(geom); // assign two materials var meshMaterial = new THREE.MeshNormalMaterial(); meshMaterial.side = THREE.DoubleSide; var wireFrameMat = new THREE.MeshBasicMaterial(); wireFrameMat.wireframe = true; // create a multimaterial var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]); return mesh; } function createLine(shape, spaced) { console.log(shape); if (!spaced) { var mesh = new THREE.Line(shape.createPointsGeometry(10), new THREE.LineBasicMaterial({ color: 0xff3333, line 2 })); return mesh; } else { //three.js的该方法错误createSpacedPointsGeometry var points=shape.createSpacedPointsGeometry(3); var mesh = new THREE.Line(points, new THREE.LineBasicMaterial({ color: 0xff3333, line 2 })); return mesh; } } function render() { //stats.update(); shapeMesh.rotation.y = step += 0.01; // render using requestAnimationFrame requestAnimationFrame(render); webGLRenderer.render(scene, camera); } } window.onload = init; </script> </body> </html>

     二、三维几何体

      2.1 BoxGeometry:立方体 new THREE.BoxGeometry(width,height,depth,widthSegements,heightSegements,depthSegements)

    <!DOCTYPE html>
    
    <html>
    
    <head>
        <title>Example 05.04 - Basic 2D geometries - Cube</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 {
                /* set margin to 0 and overflow to hidden, to go fullscreen */
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
    
    <div id="Stats-output">
    </div>
    <!-- Div which will hold the Output -->
    <div id="WebGL-output">
    </div>
    
    <!-- Javascript code that runs our Three.js examples -->
    <script type="text/javascript">
    
        // once everything is loaded, we run our Three.js stuff.
        function init() {
    
            var stats = initStats();
    
            // create a scene, that will hold all our elements such as objects, cameras and lights.
            var scene = new THREE.Scene();
    
            // create a camera, which defines where we're looking at.
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    
            // create a render and set the size
            var webGLRenderer = new THREE.WebGLRenderer();
            webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
            webGLRenderer.setSize(window.innerWidth, window.innerHeight);
            webGLRenderer.shadowMapEnabled = true;
    
            var cube = createMesh(new THREE.BoxGeometry(10, 10, 10, 1, 1, 1));
            // add the sphere to the scene
            scene.add(cube);
    
            // position and point the camera to the center of the scene
            camera.position.x = -20;
            camera.position.y = 30;
            camera.position.z = 40;
            camera.lookAt(new THREE.Vector3(10, 0, 0));
    
    
            // add spotlight for the shadows
            var spotLight = new THREE.SpotLight(0xffffff);
            spotLight.position.set(-40, 60, -10);
            scene.add(spotLight);
    
            // add the output of the renderer to the html element
            document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
    
            // call the render function
            var step = 0;
    
    
            // setup the control gui
            var controls = new function () {
    
                this.width = cube.children[0].geometry.parameters.width;
                this.height = cube.children[0].geometry.parameters.height;
                this.depth = cube.children[0].geometry.parameters.depth;
    
                this.widthSegments = cube.children[0].geometry.parameters.widthSegments;
                this.heightSegments = cube.children[0].geometry.parameters.heightSegments;
                this.depthSegments = cube.children[0].geometry.parameters.depthSegments;
    
    
                this.redraw = function () {
                    // remove the old plane
                    scene.remove(cube);
                    // create a new one
                    cube = createMesh(new THREE.BoxGeometry(controls.width, controls.height, controls.depth, Math.round(controls.widthSegments), Math.round(controls.heightSegments), Math.round(controls.depthSegments)));
                    // add it to the scene.
                    scene.add(cube);
                };
            };
    
            var gui = new dat.GUI();
            gui.add(controls, 'width', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'height', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'depth', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'widthSegments', 0, 10).onChange(controls.redraw);
            gui.add(controls, 'heightSegments', 0, 10).onChange(controls.redraw);
            gui.add(controls, 'depthSegments', 0, 10).onChange(controls.redraw);
            render();
    
            function createMesh(geom) {
    
                // assign two materials
                var meshMaterial = new THREE.MeshNormalMaterial();
                meshMaterial.side = THREE.DoubleSide;
                var wireFrameMat = new THREE.MeshBasicMaterial();
                wireFrameMat.wireframe = true;
    
                // create a multimaterial
                var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]);
    
                return mesh;
            }
    
            function render() {
                stats.update();
    
                cube.rotation.y = step += 0.01;
    
                // render using requestAnimationFrame
                requestAnimationFrame(render);
                webGLRenderer.render(scene, camera);
            }
    
            function initStats() {
    
                var stats = new Stats();
                stats.setMode(0); // 0: fps, 1: ms
    
                // Align top-left
                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>

      2.2 SphereGeometry球体

      参数:radius半径,

        widthSegements竖直方向分段,

        heightSegments水平方向分段,

        phiStart从x轴的什么地方开始绘制0-2*pi,

        phiLength绘制多少弧度,

        thetaStart从y轴的什么地方开始绘制,

        thetaLength绘制多少弧度

    <!DOCTYPE html>
    
    <html>
    
    <head>
        <title>Example 05.05 - Basic 3D geometries - Sphere</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 {
                /* set margin to 0 and overflow to hidden, to go fullscreen */
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
    
    <div id="Stats-output">
    </div>
    <!-- Div which will hold the Output -->
    <div id="WebGL-output">
    </div>
    
    <!-- Javascript code that runs our Three.js examples -->
    <script type="text/javascript">
    
        // once everything is loaded, we run our Three.js stuff.
        function init() {
    
            var stats = initStats();
    
            // create a scene, that will hold all our elements such as objects, cameras and lights.
            var scene = new THREE.Scene();
    
            // create a camera, which defines where we're looking at.
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    
            // create a render and set the size
            var webGLRenderer = new THREE.WebGLRenderer();
            webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
            webGLRenderer.setSize(window.innerWidth, window.innerHeight);
            webGLRenderer.shadowMapEnabled = true;
    
            var sphere = createMesh(new THREE.SphereGeometry(4, 10, 10));
            // add the sphere to the scene
            scene.add(sphere);
    
            // position and point the camera to the center of the scene
            camera.position.x = -20;
            camera.position.y = 30;
            camera.position.z = 40;
            camera.lookAt(new THREE.Vector3(10, 0, 0));
    
    
            // add the output of the renderer to the html element
            document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
    
            // call the render function
            var step = 0;
    
    
            // setup the control gui
            var controls = new function () {
                // we need the first child, since it's a multimaterial
                this.radius = sphere.children[0].geometry.parameters.radius;
                this.widthSegments = sphere.children[0].geometry.parameters.widthSegments;
                this.heightSegments = sphere.children[0].geometry.parameters.heightSegments;
                this.phiStart = 0;
                this.phiLength = Math.PI * 2;
                this.thetaStart = 0;
                this.thetaLength = Math.PI;
    
    
                this.redraw = function () {
                    // remove the old plane
                    scene.remove(sphere);
                    // create a new one
              var r=controls.radius;
              var ws=controls.widthSegments;
              var hs= controls.heightSegments;
    var ps=controls.phiStart;
    var pl=controls.phiLength;
    var ts=controls.thetaStart;
    var tl=controls.thetaLength

              var geo=new THREE.SphereGeometry(r, ws,hs , ps,pl , ts,tl )
    sphere = createMesh(geo); // add it to the scene. scene.add(sphere); }; }; var gui = new dat.GUI(); gui.add(controls, 'radius', 0, 40).onChange(controls.redraw); gui.add(controls, 'widthSegments', 0, 20).onChange(controls.redraw); gui.add(controls, 'heightSegments', 0, 20).onChange(controls.redraw); gui.add(controls, 'phiStart', 0, 2 * Math.PI).onChange(controls.redraw); gui.add(controls, 'phiLength', 0, 2 * Math.PI).onChange(controls.redraw); gui.add(controls, 'thetaStart', 0, 2 * Math.PI).onChange(controls.redraw); gui.add(controls, 'thetaLength', 0, 2 * Math.PI).onChange(controls.redraw); render(); function createMesh(geom) { // assign two materials var meshMaterial = new THREE.MeshNormalMaterial(); meshMaterial.side = THREE.DoubleSide; var wireFrameMat = new THREE.MeshBasicMaterial(); wireFrameMat.wireframe = true; // create a multimaterial var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]); return mesh; } function render() { stats.update(); sphere.rotation.y = step += 0.01; // render using requestAnimationFrame requestAnimationFrame(render); webGLRenderer.render(scene, camera); } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left 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>

      2.3 CylinderGeometry:构建圆柱体

      参数:radiusTop:圆柱顶部的半径

          radiusBottom:圆柱底部的半径

          height:圆柱体的高度

          segmentsX:沿x轴,即竖向分割为多少段

        segmentsY:沿Y轴,即横向分割为多少段

        openEnded:网格顶部和底部是否封闭

    <!DOCTYPE html>
    
    <html>
    
    <head>
        <title>Example 05.07 - Basic 3D geometries - Cylinder</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 {
                /* set margin to 0 and overflow to hidden, to go fullscreen */
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
    
    <div id="Stats-output">
    </div>
    <!-- Div which will hold the Output -->
    <div id="WebGL-output">
    </div>
    
    <!-- Javascript code that runs our Three.js examples -->
    <script type="text/javascript">
    
        // once everything is loaded, we run our Three.js stuff.
        function init() {
    
            var stats = initStats();
    
            // create a scene, that will hold all our elements such as objects, cameras and lights.
            var scene = new THREE.Scene();
    
            // create a camera, which defines where we're looking at.
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    
            // create a render and set the size
            var webGLRenderer = new THREE.WebGLRenderer();
            webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
            webGLRenderer.setSize(window.innerWidth, window.innerHeight);
            webGLRenderer.shadowMapEnabled = true;
    
            var cylinder = createMesh(new THREE.CylinderGeometry(20, 20, 20));
            // add the sphere to the scene
            scene.add(cylinder);
    
            // position and point the camera to the center of the scene
            camera.position.x = -30;
            camera.position.y = 40;
            camera.position.z = 50;
            camera.lookAt(new THREE.Vector3(10, 0, 0));
    
            // add the output of the renderer to the html element
            document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
    
            // call the render function
            var step = 0;
    
    
            // setup the control gui
            var controls = new function () {
                // we need the first child, since it's a multimaterial
    
                this.radiusTop = 20;
                this.radiusBottom = 20;
                this.height = 20;
    
                this.radialSegments = 8;
                this.heightSegments = 8;
    
                this.openEnded = false;
    
                this.redraw = function () {
                    // remove the old plane
                    scene.remove(cylinder);
                    // create a new one
                    var rt=controls.radiusTop;//圆柱顶部的半径,可以为负数
                    var rb=controls.radiusBottom;//圆柱底部的半径
                    var h=controls.height;//圆柱体的高度
                    var rs=controls.radialSegments;//圆柱体竖向的段数
                    var hs=controls.heightSegments;//圆柱体横向的段数
                    var oe=controls.openEnded;//圆柱体的底部和顶部是否封闭
                    cylinder = createMesh(new THREE.CylinderGeometry(rt, rb, h,rs , hs,oe ));
                    // add it to the scene.
                    scene.add(cylinder);
                };
            };
    
            var gui = new dat.GUI();
            gui.add(controls, 'radiusTop', -40, 40).onChange(controls.redraw);
            gui.add(controls, 'radiusBottom', -40, 40).onChange(controls.redraw);
            gui.add(controls, 'height', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'radialSegments', 1, 20).step(1).onChange(controls.redraw);
            gui.add(controls, 'heightSegments', 1, 20).step(1).onChange(controls.redraw);
            gui.add(controls, 'openEnded').onChange(controls.redraw);
    
    
            render();
    
            function createMesh(geom) {
    
                // assign two materials
                var meshMaterial = new THREE.MeshNormalMaterial();
                meshMaterial.side = THREE.DoubleSide;
                var wireFrameMat = new THREE.MeshBasicMaterial();
                wireFrameMat.wireframe = true;
    
                // create a multimaterial
                var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]);
    
                return mesh;
            }
    
            function render() {
                stats.update();
    
                cylinder.rotation.y = step += 0.01;
    
                // render using requestAnimationFrame
                requestAnimationFrame(render);
                webGLRenderer.render(scene, camera);
            }
    
            function initStats() {
    
                var stats = new Stats();
                stats.setMode(0); // 0: fps, 1: ms
    
                // Align top-left
                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>

     

      2.4 圆环RingGeometry:类似于甜甜圈

      参数:radius:半径,整个圆环的半径

        tube:圆环的半径,注意与radius的区别

        radialSegments:沿圆环长度方向分割的段数

        tubularSegments:沿圆环宽度方向分割的段数

        arc:绘制多少圆环,即是否为2*pi

    <!DOCTYPE html>
    
    <html>
    
    <head>
        <title>Example 05.09 - Basic 3D geometries - Ring</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 {
                /* set margin to 0 and overflow to hidden, to go fullscreen */
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
    
    <div id="Stats-output">
    </div>
    <!-- Div which will hold the Output -->
    <div id="WebGL-output">
    </div>
    
    <!-- Javascript code that runs our Three.js examples -->
    <script type="text/javascript">
    
        // once everything is loaded, we run our Three.js stuff.
        function init() {
    
            var stats = initStats();
    
            // create a scene, that will hold all our elements such as objects, cameras and lights.
            var scene = new THREE.Scene();
    
            // create a camera, which defines where we're looking at.
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    
            // create a render and set the size
            var webGLRenderer = new THREE.WebGLRenderer();
            webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
            webGLRenderer.setSize(window.innerWidth, window.innerHeight);
            webGLRenderer.shadowMapEnabled = true;
    
            var torus = createMesh(new THREE.RingGeometry());
            // add the sphere to the scene
            scene.add(torus);
    
            // position and point the camera to the center of the scene
            camera.position.x = -30;
            camera.position.y = 40;
            camera.position.z = 50;
            camera.lookAt(new THREE.Vector3(10, 0, 0));
    
            // add the output of the renderer to the html element
            document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
    
            // call the render function
            var step = 0;
    
    
            // setup the control gui
            var controls = new function () {
                // we need the first child, since it's a multimaterial
    
                this.innerRadius = 0;
                this.outerRadius = 50;
                this.thetaSegments = 8;
                this.phiSegments = 8;
                this.thetaStart = 0;
                this.thetaLength = Math.PI * 2;
    
                this.redraw = function () {
                    // remove the old plane
                    scene.remove(torus);
                    // create a new one
                    var ir=controls.innerRadius;
                    var or=controls.outerRadius;
                    var tseg=controls.thetaSegments;
                    var ps=controls.phiSegments;
                    var ts=controls.thetaStart;
                    var tl=controls.thetaLength;
                    torus = createMesh(new THREE.RingGeometry(ir,or ,tseg ,ps , ts, tl));
                    // add it to the scene.
                    scene.add(torus);
                };
            };
    
            var gui = new dat.GUI();
            gui.add(controls, 'innerRadius', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'outerRadius', 0, 100).onChange(controls.redraw);
            gui.add(controls, 'thetaSegments', 1, 40).step(1).onChange(controls.redraw);
            gui.add(controls, 'phiSegments', 1, 20).step(1).onChange(controls.redraw);
            gui.add(controls, 'thetaStart', 0, Math.PI * 2).onChange(controls.redraw);
            gui.add(controls, 'thetaLength', 0, Math.PI * 2).onChange(controls.redraw);
    
    
            render();
    
            function createMesh(geom) {
    
                // assign two materials
                var meshMaterial = new THREE.MeshNormalMaterial();
                meshMaterial.side = THREE.DoubleSide;
                var wireFrameMat = new THREE.MeshBasicMaterial();
                wireFrameMat.wireframe = true;
    
                // create a multimaterial
                var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]);
    
                return mesh;
            }
    
            function render() {
                stats.update();
    
                torus.rotation.y = step += 0.01;
    
                // render using requestAnimationFrame
                requestAnimationFrame(render);
                webGLRenderer.render(scene, camera);
            }
    
            function initStats() {
    
                var stats = new Stats();
                stats.setMode(0); // 0: fps, 1: ms
    
                // Align top-left
                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>

      2.5 TorusKnotGeometry环面纽结

      参数:radius:半径

        tube:环的实际半径

        radialSegments:沿圆环长度方向分割的段数

        tubularSegments:沿圆环宽度方向分割的段数

        p:多久旋转一次

        q:绕其内部旋转多少次

        heightScale:通过该属性可以拉伸环面纽结

     

    <!DOCTYPE html>
    
    <html>
    
    <head>
        <title>Example 05.08 - Basic 3D geometries - Torusknot</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 {
                /* set margin to 0 and overflow to hidden, to go fullscreen */
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
    
    <div id="Stats-output">
    </div>
    <!-- Div which will hold the Output -->
    <div id="WebGL-output">
    </div>
    
    <!-- Javascript code that runs our Three.js examples -->
    <script type="text/javascript">
    
        // once everything is loaded, we run our Three.js stuff.
        function init() {
    
            var stats = initStats();
    
            // create a scene, that will hold all our elements such as objects, cameras and lights.
            var scene = new THREE.Scene();
    
            // create a camera, which defines where we're looking at.
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    
            // create a render and set the size
            var webGLRenderer = new THREE.WebGLRenderer();
            webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
            webGLRenderer.setSize(window.innerWidth, window.innerHeight);
            webGLRenderer.shadowMapEnabled = true;
    
            var knot = createMesh(new THREE.TorusKnotGeometry(10, 1, 64, 8, 2, 3, 1));
            // add the sphere to the scene
            scene.add(knot);
    
            // position and point the camera to the center of the scene
            camera.position.x = -30;
            camera.position.y = 40;
            camera.position.z = 50;
            camera.lookAt(new THREE.Vector3(10, 0, 0));
    
            // add the output of the renderer to the html element
            document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
    
            // call the render function
            var step = 0;
    
    
            // setup the control gui
            var controls = new function () {
                // we need the first child, since it's a multimaterial
                this.radius = knot.children[0].geometry.parameters.radius;
                this.tube = 0.3;
                this.radialSegments = knot.children[0].geometry.parameters.radialSegments;
                this.tubularSegments = knot.children[0].geometry.parameters.tubularSegments;
                this.p = knot.children[0].geometry.parameters.p;
                this.q = knot.children[0].geometry.parameters.q;
                this.heightScale = knot.children[0].geometry.parameters.heightScale;
    
                this.redraw = function () {
                    // remove the old plane
                    scene.remove(knot);
                    // create a new one
                    var r=controls.radius;
                    var t=controls.tube;
                    var rs=Math.round(controls.radialSegments);
                    var ts=Math.round(controls.tubularSegments);
                    var p=Math.round(controls.p);
                    var q=Math.round(controls.q);
                    var hs=controls.heightScale;
                    knot = createMesh(new THREE.TorusKnotGeometry(r,t , rs, ts, p,q ,hs ));
                    // add it to the scene.
                    scene.add(knot);
                };
            };
    
            var gui = new dat.GUI();
            gui.add(controls, 'radius', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'tube', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'radialSegments', 0, 400).step(1).onChange(controls.redraw);
            gui.add(controls, 'tubularSegments', 1, 20).step(1).onChange(controls.redraw);
            gui.add(controls, 'p', 1, 10).step(1).onChange(controls.redraw);
            gui.add(controls, 'q', 1, 15).step(1).onChange(controls.redraw);
            gui.add(controls, 'heightScale', 0, 5).onChange(controls.redraw);
    
    
            render();
    
            function createMesh(geom) {
    
                // assign two materials
                var meshMaterial = new THREE.MeshNormalMaterial({});
                meshMaterial.side = THREE.DoubleSide;
    
                // create a multimaterial
                var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial]);
    
                return mesh;
            }
    
            function render() {
                stats.update();
    
                knot.rotation.y = step += 0.01;
    
                // render using requestAnimationFrame
                requestAnimationFrame(render);
                webGLRenderer.render(scene, camera);
            }
    
            function initStats() {
    
                var stats = new Stats();
                stats.setMode(0); // 0: fps, 1: ms
    
                // Align top-left
                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>

      2.6 多面体PolyhedronGeometry

      参数:vertices顶点

      faces:面

      radius:多面体的半径,即大小,这里只是缩放,并不是真的改变坐标

      detail:当该值为1时,x面体的每个面分割为x个面体,当参数为2时,在参数为1的基础上,再次将各个面分割为x面体,依次类推

      

    <!DOCTYPE html>
    
    <html>
    
    <head>
        <title>Example 05.09 - Basic 3D geometries - Polyhedron</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 {
                /* set margin to 0 and overflow to hidden, to go fullscreen */
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
    
    <div id="Stats-output">
    </div>
    <!-- Div which will hold the Output -->
    <div id="WebGL-output">
    </div>
    
    <!-- Javascript code that runs our Three.js examples -->
    <script type="text/javascript">
    
        // once everything is loaded, we run our Three.js stuff.
        function init() {
    
            var stats = initStats();
    
            // create a scene, that will hold all our elements such as objects, cameras and lights.
            var scene = new THREE.Scene();
    
            // create a camera, which defines where we're looking at.
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    
            // create a render and set the size
            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));
            // add the sphere to the scene
            scene.add(polyhedron);
    
            // position and point the camera to the center of the scene
            camera.position.x = -30;
            camera.position.y = 40;
            camera.position.z = 50;
            camera.lookAt(new THREE.Vector3(10, 0, 0));
    
            // add the output of the renderer to the html element
            document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
    
            // call the render function
            var step = 0;
    
    
            // setup the control gui
            var controls = new function () {
                // we need the first child, since it's a multimaterial
                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':
                        //正20面体
              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;
                    }
    
                    // add it to the scene.
                    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) {
    
                // assign two materials
                var meshMaterial = new THREE.MeshNormalMaterial();
                meshMaterial.side = THREE.DoubleSide;
                var wireFrameMat = new THREE.MeshBasicMaterial();
                wireFrameMat.wireframe = true;
    
                // create a multimaterial
                var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]);
    
                return mesh;
            }
    
            function render() {
                stats.update();
    
                polyhedron.rotation.y = step += 0.01;
    
                // render using requestAnimationFrame
                requestAnimationFrame(render);
                webGLRenderer.render(scene, camera);
            }
    
            function initStats() {
    
                var stats = new Stats();
                stats.setMode(0); // 0: fps, 1: ms
    
                // Align top-left
                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>
  • 相关阅读:
    React-Hooks
    RC-Select 学习笔记
    React Strict Mode
    CSSMotion VS animation in Angular
    jquery中has方法
    jquery中对于extend方法的使用
    一篇对于在jquery中使用jsonp技术介绍
    对于table元素的总结
    css3布局相关样式
    移动端去掉按钮点击热区
  • 原文地址:https://www.cnblogs.com/amy2011/p/6357559.html
Copyright © 2020-2023  润新知