Intersecting rays with Three.js

The coding below was crafted to pinpoint the intersection point with a 3D shape. While it functions as intended, there's an issue where if two intersection points exist with the shape, only the farthest one is returned instead of the closest one. How can I modify this code to obtain the nearest intersection?

  /* Creating a cube here*/

            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);//adjust values



    /* Ray creation */


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

Inspecting intersects[0].point reveals only the furthest intersected face of the cube rather than the first one. The objective of this snippet is to trigger an event only when clicking on vertices. Consequently, additional code was written to calculate the Euclidean distance between the clicked point and all vertices, aiming to return the vertex closest to the click point. Any alternative methods for triggering events exclusively on vertex clicks are appreciated.

Answer №1

A fundamental concept behind ray casting is projecting a ray perpendicular to a plane to determine which objects the ray intersects with.

To retrieve the first element, simply add the code snippet below:

var hits = caster.rayintersectObjects(targets);

if (hits.length > 0) {
       var firstHitObject = hits[0];
       // this will return the initial object hit by the ray if there are multiple intersections.
    }

You can also check out another related post on Stack Overflow that delves deeper into understanding the mechanics of raycasting for further clarification.

Answer №2

Check out this example and try to navigate through it. Don't forget to keep an eye on the messages displayed 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);
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Just beginning my journey with node.js and looking for guidance on implementing an npm module into my front-end vanilla JavaScript project

Starting off, I must admit that my knowledge of node.js and web development is quite limited. Despite searching through stackoverflow and Google for a solution, I've come up empty-handed. My main concern is figuring out the necessary steps to take sin ...

Customized function enabling dynamic menu display based on varying screen dimensions

Looking for assistance with JS and jQuery as I am relatively new to it. Any help would be greatly appreciated... I'm currently working on a responsive header where I want to implement onclick functions for mobile and tablet resolutions only. I' ...

What is the process of integrating an EJS file into the app.js file?

Within my index.ejs file, I have included a script tag containing JavaScript for DOM manipulation. Now, I am looking to access a variable declared within this file from my app.js file. How can I make this happen? When referencing a variable in an ejs file ...

Modifying properties within child components

Within my parent Vue Page, I have inserted a FormInput component inside my form. new.vue <b-form @submit.prevent="submit"> <FormInput :name="name"/> <b-button @click="submit">Save</b-button> <b-form> <script> i ...

When JSONP is used in cross-domain AJAX calls, it retrieves plain JSON data

I am facing an issue with an API that I need to integrate. The API provides JSON data, but as it involves a cross domain AJAX call, I have to utilize jsonp. $.ajax({ type: "GET", url: url + query, ...

Exploring the interactive features of discord.js version 12

Currently, I have a bot set up to log when invites are created, but the logs are only going to a specific channel ID that I designated. I would like to make it so that this can be changed on a per-server basis. Intended Output User: !log channel (CHANNEL ...

The parameter always comes up empty when using $state.go in AngularJS

When trying to pass one parameter using `$stete.go`, I encountered an issue. ROUTER $stateProvider.state('login.signin', { url: '/signin', params: { login_event: '' }, templateUrl: "assets/views/login ...

Top method for validating a function that generates an observable operator

What is the most effective approach to testing a function that returns an observable with the tap operator? operations(numbers): Observable{ const sumValue = numbers[0]+numbers[1] return sumService.getOperations(sumValue).pipe(tap(randomOperationValue ...

The collaboration of Nodemon and Redwood-Broker

I have been running Nodemon in my express app without any special configuration. In my package.json file, I only have the following: "scripts": { "start:dev": "nodemon app/app.js" } ... Everything runs smoothly until I make changes and Nodemon attempts ...

Previewing multiple selected files in Angular interface

As a newcomer to Angular, I am currently working on a feature that involves selecting multiple files and displaying their previews before uploading them to the server. While my code works correctly when individual files are selected one at a time, it fail ...

Verifying internet connectivity and updating content using jQuery and JavaScript

Upon loading the page, the following functionality occurs without triggering a click event: The updated code attempts to determine if the internet connection is active. If the connection is off, the 'link' on the page will be disabled (non-click ...

Export individual mesh via the threejs exporter in the Blender console

I am currently working with Blender 2.76b and the threejs exporter v1.5.0. My objective is to export each individual mesh within the Blender scene. I have observed that when a single mesh is selected, the io_three exports only that specific mesh. In an att ...

Combining the powers of Javascript and Drupal can create

My current setup includes an "open video" button and a form that triggers an ajax call to render files with the corresponding buttons when users click on handouts or videos. I have encountered a problem: Whenever I click on "open the video" after renderi ...

What is the connection between serialization and JSON?

Can you explain serialization? Serialization is the process of converting an object into a stream of bytes, allowing it to be sent over a network or stored in a file. This allows the object to be reconstructed later on. What exactly is JSON? JSON stands ...

Transferring an MSAL token to the backend with the help of Axios

I encountered an issue while attempting to send the user ID, which was previously decoded from a JWT token along with user input data. The problem arises when I try to send the data and receive an exception in the backend indicating that the request array ...

This browser does not support the React Three Fiber mesh tag

I encountered an error while following a 3D portfolio tutorial on Youtube. When attempting to render a mesh, the console displayed a warning stating that "This element is unrecognized in this browser". Although the browser was able to render the rest of th ...

Is it not possible to use array splice with a string that is in array format (i.e., split string

Why doesn't array splice work with a string that has been formatted into an array using the split() method? function _formatText(text) { var textList = text.replace(/\s+/g, ",").split(","); return textList.splice(1, 0, "<br />").join ...

Map does not provide zero padding for strings, whereas forEach does

Currently working on developing crypto tools, I encountered an issue while attempting to utilize the map function to reduce characters into a string. Strangely enough, one function works perfectly fine, while the other fails to 0 pad the string. What could ...

Uh-oh! It seems like there is a deployment error in NextJS on Vercel. The issue is that Nested

Suddenly, my middleware ceased to function properly during deployment. The error message states: > Build error occurred NestedMiddlewareError: Nested Middleware is not allowed, found: pages/_middleware Please relocate your code to a single file at /midd ...

Error: The expression `xmlDoc.load` returns a value of undefined, which is not an object

My current challenge involves loading an XML file using Javascript in IE, Firefox, and Safari. I have yet to find a function that works well across all three browsers. The load function I am currently using is similar to the one found in w3schools tutorial ...