javascript 三.js raycaster 交集

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26371847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 05:52:46  来源:igfitidea点击:

Three.js raycaster intersection

javascriptthree.jsraycasting

提问by Stefano Maglione

I wrote the code below to get intersection point with a 3d shape. It works well but if there are two intersection point with shape, it returns me only the farest intersection while I need the nearest intersection with the shape. How can I do to get the nearest intersection?

我编写了下面的代码来获得与 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");} 

If I check intersects[0].point I can only see the farest point face of cube intersected and not the first (for example,if you look at a cube in front of you and make a ray,this ray before intersect the first face and after intersect second face behind the first.) The goal of this code is to create an event only when you click on vertices. So after this I wrote code to calculate the euclidean distance from point of click and all vertices and return the vertice nearest to the point of click. If you have other idea to fire an event only when you click on vertices is welcome.

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

回答by Shiva

Yes, the basic idea of ray castingis that we project a ray perpendicular to the plane we find out the list of objects that the ray has intersected.

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

So all you have to do to access the first element is adding the following piece of code.

因此,访问第一个元素所需要做的就是添加以下代码。

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

Here is one of my other SO postin which I have explained things in a bit more detailed way, you can refer it to better understand how raycasting functions.

这是我的另一篇 SO 帖子,其中我以更详细的方式解释了一些事情,您可以参考它以更好地了解光线投射的功能。

回答by Almaz Vildanov

Try to make through this example. Look at messages in the console.

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

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