首页 > 解决方案 > 在 three.js 中使用点云创建平面网格

问题描述

我创建了点云,所有点都在一个精确的平面上。我希望鼠标悬停时突出显示点云并显示为矩形。为此,我认为必须首先将点云转换为网格。
我已经搜索了几个小时并尝试阅读 thee.js 文档。但找不到任何解决方案。你能帮我把这个点云转换成网格吗?非常感谢

        <script>

        if ( WEBGL.isWebGLAvailable() === false ) {
            document.body.appendChild( WEBGL.getWebGLErrorMessage() );
        }
        var camera, scene, renderer, controls;
        init();
        animate();

        function init() {

            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            document.body.appendChild( renderer.domElement );
            scene = new THREE.Scene();
            camera = new THREE.PerspectiveCamera( 45.0, window.innerWidth / window.innerHeight, 5, 3500 );
            camera.position.z = 2500;
            controls = new THREE.TrackballControls( camera, renderer.domElement );
            createScene();
        }

        function createScene() {
                scene = new THREE.Scene();
                scene.background = new THREE.Color( 0x000000 );
                var geometry = new THREE.BufferGeometry();
                var positions = [];

                for ( var i = 0; i < 500; i ++ ) {
                    for ( var j = 0; j < 300; j ++ ) {
                    var y = j;
                    var x = i; 
                    var z = 0;
                    positions.push( x, y, z );
                    }
                }

                geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );

                var material = new THREE.PointsMaterial( {color: 0xFFFFFF} );
                points = new THREE.Points( geometry, material );
                scene.add( points );
        }

        function animate( time ) {

            requestAnimationFrame( animate );
            controls.update();
            renderer.render( scene, camera );

        }

        </script>

标签: javascriptthree.js

解决方案


这是您的示例的快速而肮脏的修改,基本上它创建了一个与您的点云具有相同尺寸的薄框,并在鼠标经过时切换其可见性(使用光线投射器)。据我所知,没有直接/内置的方法可以将点云变成平面/网格。

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Three.js - wall construction</title>
        <meta charset="utf-8">
        <script src="js/three.js"></script>
        <script src="js/TrackballControls.js"></script>
    </head>
    <body style="margin:0;">
        <script>

        if ( WEBGL.isWebGLAvailable() === false ) {
            document.body.appendChild( WEBGL.getWebGLErrorMessage() );
        }
        var camera, scene, renderer, controls, box, boxMaterial;
        init();
        animate();

        function init() {


          renderer = new THREE.WebGLRenderer( { antialias: true } );
          renderer.setPixelRatio( window.devicePixelRatio );
          renderer.setSize( window.innerWidth, window.innerHeight );
          document.body.appendChild( renderer.domElement );
          scene = new THREE.Scene();
          camera = new THREE.PerspectiveCamera( 45.0, window.innerWidth / window.innerHeight, 5, 3500 );
          camera.position.z = 2500;
          controls = new THREE.TrackballControls( camera, renderer.domElement );
          createScene();
          renderer.domElement.addEventListener('mousemove', onMouseMove, false); 
        }

        function createScene() {

          scene = new THREE.Scene();
          scene.background = new THREE.Color( 0x000000 );
          var geometry = new THREE.BufferGeometry();
          var positions = [];

          for ( var i = -250; i < 250; ++i) {
              for ( var j = -150; j < 150; ++j) {
                positions.push(i, j, 0);
              }
          }

          geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );

          var material = new THREE.PointsMaterial({color: 0xFFFFFF});
          points = new THREE.Points(geometry, material);
          scene.add(points);

          //create box based on pointcloud extends  
          var geometry = new THREE.BoxGeometry(500, 300, 1 );
          boxMaterial = new THREE.MeshBasicMaterial({color: 0x0000FF});
          boxMaterial.visible = false //set invisible by default
          box = new THREE.Mesh(geometry, boxMaterial);
          scene.add(box);
        }

        function onMouseMove (e) {

          var pointer = {
            x: (e.clientX / window.innerWidth ) * 2 - 1,
            y: - ( e.clientY / window.innerHeight ) * 2 + 1
          }  

          var raycaster = new THREE.Raycaster()
          raycaster.setFromCamera(pointer, camera)

          var intersects = raycaster.intersectObjects([box])

          boxMaterial.visible = !!intersects.length
        }

        function animate(time) {
          requestAnimationFrame(animate);
          controls.update();
          renderer.render(scene, camera);
        }

        </script>
    </body>
</html>

推荐阅读