zoukankan      html  css  js  c++  java
  • 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>
  • 相关阅读:
    8.10
    今日头条笔试题 1~n的每个数,按字典序排完序后,第m个数是什么?
    Gym 100500B Conference Room(最小表示法,哈希)
    CodeForces 438D The Child and Sequence(线段树)
    UVALIVE 6905 Two Yachts(最小费用最大流)
    Gym Conference Room (最小表示法,哈希)
    hdu 2389 Rain on your Parade(二分图HK算法)
    Codeforces Fox And Dinner(最大流)
    zoj 3367 Counterfeit Money(dp)
    ZOJ3370. Radio Waves(2-sat)
  • 原文地址:https://www.cnblogs.com/amy2011/p/6357559.html
Copyright © 2011-2022 走看看