Three.js 光线投射交点

4
我写了下面的代码来获取与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,我只能看到立方体相交的最远点面,而不是第一个(例如,如果您在面前看一个立方体并制作射线,这条射线在相交第一个面之前并在第一个面后相交第二个面。) 此代码的目标是仅在单击顶点时创建事件。 因此,在此之后,我编写了代码来计算从单击点到所有顶点的欧几里得距离,并返回最接近单击点的顶点。 如果您有其他想法仅在单击顶点时触发事件,请随时提出。
2个回答

5

是的,光线投射的基本思想是我们垂直投射一条光线到平面上,找出光线与之相交的物体列表。

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

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.
    }

这里是我的另一个SO帖子之一,我在其中更详细地解释了事情,您可以参考它以更好地理解射线投射的工作原理。


我已经使用了intersects[0],但是如果我有一个立方体,一条射线首先与最靠近我的立方体面相交,然后与立方体的最远面相交,并且仅返回与最远面相交的交点。 @Shiva - Stefano Maglione
@StefanoMaglione:请在问题中也包含这部分代码,这样我们就可以找到出了什么问题。 - Shiva
我尝试像这样记录距离 console.log(intersects[0].distance); 对我来说似乎工作得很好。 - Shiva
如果您查看点的属性,您可以看到,如果您单击第一个面,它将返回第一个面后面的坐标。我认为我必须避免这种解决方案。我可以问一下你有关仅在单击顶点时触发事件的想法吗?谢谢 @Shiva - Stefano Maglione

0

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接