How to position a particle at the center of the visible screen using Three.js

I have a unique scenario in which I am using a ParticleSystem with thousands of particles spread across the screen. When zooming and panning using the OrbitControls, I am looking to identify the particle closest to the center of the visible area.

There are two main components to this task. Firstly, it is necessary to determine the central vertex of the visible area. Subsequently, we must apply the distance formula to all particles to pinpoint the one nearest to the central vertex. I hope there is a more efficient method than the brute force approach for the second part. While locating the nearest particle can be achieved straightforwardly through brute force, I'm uncertain about how to locate the central vertex of the visible area. Can someone guide me on how to accomplish this?

Answer №1

If you want to pinpoint a specific location in three-dimensional space, try focusing on a point directly ahead of you, approximately 10 units away, and then identify the nearest particle from that reference point.

Having experimented with this technique previously, I can confidently share this advice with you.

Learn more about Three.js Projector and Ray objects here

This approach is particularly useful for clicking on a spot on your screen and extracting a corresponding vector.

To implement this procedure: 

Initialize a projector object using THREE.Projector()
Set up an initial vector straight_ahead representing a direction relative to the camera
Transform this vector using projector.unprojectVector(straight_ahead, camera)
Adjust the vector to be offset from the camera by a specified distance (e.g., 10 units)
Identify a point in space based on the modified vector's position
Iterate through a collection of particles to find the one closest to the designated point
Keep track of the particle with the shortest distance as min_point

Answer №2

lookAt = camera.lookAt;
pos = camera.position;

min = MAX_FLOAT, min_index = -1;
foreach(particle in particle_system) {
    d = distance(particle.position, lookAt, pos);
    if( min>d ) { min_index = particle.getIndex; min = d; }
}

Where the distance function is available online, for example: http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line

This code snippet captures the process of identifying the viewing ray (lookAt vector) and determining the nearest particle to it.

EDIT:

var cam_position = camera.position,
    cam_eyeVec = getEyeVec(camera.projectionMatrix);

var min_dist = 10000000,
    min_index = -1;

for(var i=0; i<particle_count; i++) {
    var d = distance(particle[i].position, cam_eyeVec, cam_position);
    if(min_dist > d) {
         min_index = i;
         min_dist = d;
    }
}

function getEyeVec(projMat) {
    return new THREE.Vector3(projMat[8], projMat[9], projMat[10]);
}

function distance(p, n, a) {
    n = n.normalize();
    var diff = new THREE.Vector3(a.x-p.x, a.y-p.y, a.z-p.z);
    var diff_n = diff.multiply(n);
    var d = ((diff.selfSubstract(diff_n)).selfMultiply(n)).length();
    return d;
}

The calculation for getEyeVec is inspired by - eye and up vectors from viewMatrix. The approach for computing distance is based on - Distance from a point to a line.

Answer №3

While I may not be well-versed in three.js, I do have expertise in optimization algorithms. One common mistake is looping through all particles every time, which can lead to inefficiency.

A better approach is to sort the particles so that when you know the camera position, you can quickly locate the closest points without iterating through each one individually. It's akin to having an index in a database or navigating a library categorized alphabetically - you don't need to search every single item, just go directly to the relevant section and make finer comparisons as needed.

In a 2D scenario, storing particles in grids with multiple levels can significantly reduce the number of iterations required. For instance, categorizing 1 million particles based on their position relative to the center allows for efficient filtering using simple conditional statements. By organizing particles into grid locations upon creation, you can drastically minimize the computational load by focusing only on the relevant sections during runtime.

To account for particle movement, incorporating basic modular arithmetic calculations can ensure continuous tracking within the designated grid locations. Additionally, implementing a proximity threshold defines what constitutes "close enough," facilitating quicker and more accurate results even with densely clustered particles.

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

Issue arises when the function in a for loop disrupts the loop from functioning correctly

This particular script is designed to scan through a sheet for currency values and create key/value pairs for a JSON based on the column and row headers. It basically detects a currency value, then traces back row and column numbers until it reaches a non- ...

AngularJS: Understanding the 'controller as' syntax and the importance of $watch

Is it possible to subscribe to property changes when using the controller as syntax? controller('TestCtrl', function ($scope) { this.name = 'Max'; this.changeName = function () { this.name = new Date(); } // not working ...

The Webpack setup in React seems to be struggling to load a 3D model that has a GLTF extension, resulting in a 404 not found

Attempting to implement the loading of a 3D model with the .gltf extension in React using Typescript. The files within the folder containing the 3D model are .gltf, .png, and .bin files. The tools being utilized for this task include webpack and the useGLT ...

What is the process for activating angular.js animation code within your JavaScript file?

Upon reaching the app.controller section, a console.log statement is executed in the Fourth line of angular.js code, displaying output in the console. Why is the animation code not working as expected? Does the ng-repeat directive support repeating element ...

Does the sequence matter when studying JavaScript, Ajax, jQuery, and JSON?

Expanding my job opportunities is a top priority for me, which is why I am dedicated to learning JavaScript, AJAX, jQuery, and JSON. As I delve into these languages, I can see how they all have roots in JavaScript. My main inquiry is about the relationsh ...

Choosing Between Partial View with ng-route or ng-show/ng-hide: Which One is the Better Choice?

In my app, I have multiple tab views (four to five) where clicking on each tab will display content based on the tab selection. After trying two approaches - ng-route and ng-show/ng-hide, I found that ng-show/ng-hide is more efficient in terms of performa ...

Error: The specified JavaScript library "angular" is not recognized

Attempting to develop a basic Angular application for searching names from an array in the controller. Each time the app is executed, encountering the error 'Uncaught ReferenceError: angular is not defined' in the console. Despite researching sim ...

Discovering the window scroll unit when clicking, as a page smoothly transitions to the top for a specified target position

Is there a way to achieve parallax scrolling on window scroll and navigation click simultaneously? When navigating and animating the page to the top to show the target, I also want to get the window scroll unit. How can I obtain the window scroll unit on ...

Comparing Angular 5 with --aot and Angular 5 with --aot=false configuration settings

I am having an issue with my Angular application using Angular 5.0.0 and rxjs ^5.5.2. When I run the command ng serve --aot=false, everything works fine. However, when I use ng serve --aot, I encounter the following error: core.js:1350 ERROR Error: Uncaug ...

The jQuery UI function .autocomplete() helps to enable autocomplete functionality

Autocomplete feature is successfully implemented on my website using the code below: $(function () { $("#client").autocomplete({ source: "/appointments/clients.json", minLength: 1, select: function (event, ui) { $(& ...

Steps for retrieving the URL after redirecting from the current page to another with Puppeteer

My name is Aadarshvelu and I have recently started testing my web application code using Jest with Puppeteer. I have a page where all credentials are filled using Puppeteer. However, when the 'signBtn' button is clicked, the POST process starts. ...

How can JavaScript be used to parse an XML file? Should we consider using SAX for handling large XML files

Hello everyone, I am feeling very frustrated and overwhelmed with my current situation. I have been searching everywhere for a solution but seem to be going in circles. This will be my first attempt at working with xml and it's quite daunting, espec ...

Eliminating blank attributes within an array of objects

I'm currently working on a task that involves creating an array to summarize another array. I've received valuable suggestions from various sources, including this discussion on Stack Overflow. Although the solutions provided are effective, they ...

My Javascript file is not being recognized by MVC

Initially, I created an MVC application without fully understanding that MVC is more backend-oriented than frontend-focused. I ended up building a simple website with just HTML, CSS, and Javascript files, which worked perfectly. However, when I tried to in ...

Guide on transferring object between two $states using ui-router

Visit this link for more information Expected Behavior Upon logging in, selecting a Ticker button is expected to trigger the display of matching Tags for that specific Ticker. Actual Results However, upon clicking a Ticker button after logging in, the ...

What is the best way to incorporate AngularJS data into JavaScript for use in Google Chart?

How can I leverage my AngularJS scope data in a Google Chart or JavaScript? Below is my AngularJS file: angular.module('reports').controller('ReportInfoCtrl', ['$scope', 'reports', '$rootScope','$loca ...

A step-by-step guide to creating a custom JavaScript/AJAX function

Hello everyone, I am new to the world of Ajax and JavaScript, so please bear with me as I ask my question. I have a link on my website that opens a new window using JavaScript. In this new window, I have a form that submits data to my database using PHP. ...

Jade Compilation with Gulp

Currently utilizing gulp-jade, I have encountered an error with a particular template: 557| 558| > 559| 560| .tabs-wrap(ng-show="eventExists"): .contain-center 561| 562| #room-tabs-contain.contain-disable.contain: .contain-center unexpec ...

Lazy Loading fails to deliver for Ajax Requests

I recently integrated lazy loading following David Walsh's advice (tip 1) and it initially worked perfectly. However, I encountered an issue when the images were filtered and reloaded with an ajax request. The website is built on Rails, and the images ...

Is it possible to utilize a keyboard listener to activate a tooltip upon being invoked?

I've created a basic pie chart that shows a tooltip when you click on a pie wedge. Now, I want to achieve the SAME functionality, but for div elements located OUTSIDE of the pie chart. Situation: A user focusing on the 'Cat 1' div and ...