三.js raycaster 交集

Posted

技术标签:

【中文标题】三.js raycaster 交集【英文标题】:Three.js raycaster intersection 【发布时间】:2014-12-09 21:33:48 【问题描述】:

我编写了下面的代码来获取与 3d 形状的交点。它运作良好,但如果有两个与形状的交点,它只返回最远的交点,而我需要与形状最近的交点。如何才能到最近的路口?

  /*here I create a cube*/

            var geometry0 = new THREE.Geometry()
            geometry0.vertices = [new THREE.Vector3(0.5, -0.5, 0.5), new THREE.Vector3(-0.5, -0.5, 0.5), new THREE.Vector3(-0.5, -0.5, -0.5), new THREE.Vector3(0.5, -0.5, -0.5), new THREE.Vector3(0.5, 0.5, 0.5), new THREE.Vector3(-0.5, 0.5, 0.5), new THREE.Vector3(-0.5, 0.5, -0.5), new THREE.Vector3(0.5, 0.5, -0.5)];
            geometry0.faces = [new THREE.Face3(3, 2, 1), new THREE.Face3(3, 1, 0), new THREE.Face3(4, 5, 6), new THREE.Face3(4, 6, 7), new THREE.Face3(0, 1, 5), new THREE.Face3(0, 5, 4), new THREE.Face3(1, 2, 6), new THREE.Face3(1, 6, 5), new THREE.Face3(2, 3, 7), new THREE.Face3(2, 7, 6), new THREE.Face3(3, 0, 4), new THREE.Face3(3, 4, 7)];
            geometry0.computeFaceNormals();
            geometry0.computeVertexNormals();
            var material0 = new THREE.MeshBasicMaterial(color: 0x39d2dbe7fff39d2, transparent: true, opacity: 0);
            mesh0 = new THREE.Mesh(geometry0, material0);
            egh0 = new THREE.EdgesHelper(mesh0, 0x000);
            egh0.material.linewidth = 2;
            scene.add(egh0);


            objects.push(mesh0);
            projector = new THREE.Projector();
            console.log(objects);
            mouse2D = new THREE.Vector3(0, 10000, 0.5);//controllare i valori



    /* here I create the ray */


document.addEventListener('click', onDocumentMouseClick, false);


        function onDocumentMouseClick(event) 

            event.preventDefault();

            mouse2D.x = (event.clientX / window.innerWidth) * 2 - 1;
            mouse2D.y = -(event.clientY / window.innerHeight) * 2 + 1;
             var vector = new THREE.Vector3( mouse2D.x, mouse2D.y, 0.5 );

            projector.unprojectVector( vector, camera );

            var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );


            var intersects = raycaster.intersectObjects( objects );

            if (intersects.length > 0) 
                console.log("ok"); 

如果我检查 intersects[0].point 我只能看到立方体的最远点面相交而不是第一个(例如,如果你看着你面前的一个立方体并发出一条射线,这条射线在相交之前第一个面和第二个面在第一个面之后相交。) 此代码的目标是仅在您单击顶点时创建一个事件。 所以在这之后我写了代码来计算从点击点和所有顶点的欧几里得距离 并返回离点击点最近的顶点。 如果您有其他想法仅在单击顶点时触发事件,欢迎。

【问题讨论】:

【参考方案1】:

是的,ray casting 的基本思想是我们投射一条垂直于平面的射线,我们找出射线相交的对象列表。

因此,要访问第一个元素,您只需添加以下代码。

var intersects = raycaster.intersectObjects(objects);

if (intersects.length > 0) 
       var firstIntersectedObject  = intersects[0];
       // this will give you the first intersected Object if there are multiple.
    

这里是one of my other SO post,我在其中进行了更详细的解释,您可以参考它以更好地了解光线投射的功能。

【讨论】:

我已经使用过 intersects[0] 但是如果我有一个立方体,一条射线首先与离我最近的立方体面相交,然后与立方体的最远面相交并只返回交点用最远的脸。 @Shiva @StefanoMaglione:请在问题中也包含这部分代码......这样我们就可以找到那里出了什么问题。 我试图记录这样的距离 console.log(intersects[0].distance); 对我来说似乎工作正常 如果您查看点属性,您可以看到,如果您单击第一个面,它将返回第一个面后面的坐标。我想我必须避免这种解决方案。我能问你一些想法,只在点击顶点时触发一个事件吗?谢谢。 @Shiva【参考方案2】:

尝试通过这个example。查看控制台中的消息。

<script src="js/controls/EventsControls.js"></script>

EventsControls = new EventsControls( camera, renderer.domElement );
EventsControls.draggable = false;

EventsControls.onclick = function() 

       console.log( this.focused.name );
       console.log( 'this.focusedPoint: (' + this.focusedPoint.x + ', ' +
                     this.focusedPoint.y + ', ' + this.focusedPoint.z + ')' );
       console.log( 'this.focusedDistance: ' + this.focusedDistance );



var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh ); 

EventsControls.attach( mesh );

// 

function render() 
       EventsControls.update();
       controls.update();
       renderer.render(scene, camera);

【讨论】:

以上是关于三.js raycaster 交集的主要内容,如果未能解决你的问题,请参考以下文章

Three.js raycaster 可以与组相交吗?

Three.js 中的 Raycast,只有一个投影矩阵

Three.js 隐形平面不适用于 raycaster.intersectObject

Three.js Raycaster on WebWorker

Three.js Raycaster 未检测到场景网格

three.js 2D 鼠标点击到 3d 坐标使用 raycaster