What is the process of defining a group of particles in relation to a vector path using Three.js?

In my exploration of Three.js, I have been experimenting with particle clouds and their unique properties. Many examples I have come across utilize shape geometries to generate fields of particles or random parameters for their distribution. However, I am intrigued by the idea of creating a particle cloud where each particle is positioned in relation to an invisible vector path. For instance, envision a slightly curved vector path where particles float within a specific radius, gradually tapering towards the ends to form a hotdog-shaped cloud. While I can independently create particles and vector paths, I am uncertain how to seamlessly connect the two. Any insights on the process would be greatly appreciated. Thank you!

Answer №1

To establish the path between two points, use the points p and q, where v = p - q. Any point M on the path must meet the vector equation:

M = (1 - lambda) * p + lambda * q

for any lambda in the range 0 to 1. To generate a random point on the path, generate a random lambda and apply it in the equation above:

// Define p and q as instances of THREE.Vector3
function pointOnPath(p, q) {
   var lambda = Math.random();
   var scaledp = (new THREE.Vector3()).copy(p).multiplyScalar(1 - lambda);
   var scaleq = (new THREE.Vector3()).copy(q).multiplyScalar(lambda);
   var result = (new THREE.Vector3()).addVectors(scaledp, scaleq);
   return result;
} 

Next, adjust the coordinates with a small radius to encircle the path. This is done by adding a small vector offset. How do we calculate this vector?

The sought-after vector lies on a plane perpendicular to the line connecting p and q. There are infinite vectors meeting this condition, two examples being e1 = (v.y, -v.x, 0) and e2 = (v.z, 0, -v.x). Any vector of the form lambda * e1 + mu * e2 will be perpendicular to v. Therefore, generating random lambda and mu is all that's needed.

NOTE: lambda and mu must fall within the range of [-1; 1], rather than [0; 1]. Since the offset vector will be normalized, the interval [-0.5; 0.5] will suffice as normalization will map it to [-1; 1].

function getVectorOffset(p, q, radius) {
    var v = (new THREE.Vector3()).subVectors(q, p);
    v.normalize();
    var e1 = new THREE.Vector3(v.y, -v.x, 0),
        e2 = new THREE.Vector3(v.z, 0, -v.x);
    e1.normalize();
    e2.normalize();

    var lambda = Math.random() - 0.5,
        mu = Math.random() - 0.5;
    var offset = e1.multiplyScalar(lambda).add(e2.multiplyScalar(mu));
    offset.normalize();
    offset.multiplyScalar(radius) // multiply the computed offset by the desired radius for circling

    return offset;

}

Finally, to derive your desired point:

function pointOnHotDog(p, q, radius) {
    return pointOnPath(p, q).add(getVectorOffset(p, q, radius));
}

Take a look at the working jsfiddle

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

Is JQuery the ultimate solution for creating a dynamic multi-language website?

Embarking on a new project that requires support for multiple languages. My plan is to create a jQuery/AJAX based application with all the code in jQuery, simply calling JSONs for data. What would be the most effective approach for implementing multi-lan ...

Removing the root component in ReactJS can be done on specific pages by implementing

Is there a way to remove the <header/> and <footer/> components from my signup.js and signin.js pages without altering the root index.js file? Presently, the root index.js file looks like this: class Template extends React.Component { render( ...

Increment numbers using XML elements

In my XML construction process, I start with a base XML and add elements like this: $(xml).find('PARENT').find('CHILDREN').each(function(i){ outputstr += '<lorem id="">' }) As the "parent" object appears mul ...

Is there a way to ensure that clicking a link_to only opens a partial once?

These are the files I am working with: _comment.haml %div.comment{ :id => "comment-#{comment.id}" } %hr - if current_user && current_user.id == comment.user_id || current_user && current_user.id == reel_user = link_to " ...

How can I create a dynamic height for a scrollable div?

How can I build a section with a defined height that contains a sticky header (with a dynamic height) and a scrollable body? I want the body to be scrollable, but due to the header's changing height, I'm unable to set an exact height. What should ...

Modifying the onclick function for a bootstrap glyphicon

How can I swap the .glyphicon-menu-down to glyphicon-menu-up when a user clicks on a link? Currently, it's not working as expected. Could there be an issue with my jQuery implementation? Markup <a data-toggle="collapse" data-parent="#accordion" h ...

Guide on incorporating pinching gestures for zooming in and out using JavaScript

I have been working on implementing pinch zoom in and out functionality in JavaScript. I have made progress by figuring out how to detect these gestures using touch events. var dist1=0; function start(ev) { if (ev.targetTouches.length == 2) {//checkin ...

Display multiple items from a JSON object in Django on the following page

I need to implement a feature that allows users to select multiple entries from a JSON object displayed in an HTML table. After selecting their entries and submitting, they should be redirected to a new page where only their chosen items are shown for conf ...

NestJs does not handle the JSON request body

After setting up a NestJs controller and a facade service for handling POST requests, I encountered an issue where the functionality only worked for content-type "text/plain" and not for "application/json", even though the body of the request was identical ...

Model is updated by checkbox only on the second click

Take a look at this Plunkr example here: http://plnkr.co/edit/hwVL3xtnD9hGJL?p=preview After clicking the checkbox for the first time, the model fails to update. Can you explain why? var app = angular.module('main', ['ngMaterial']) ...

Find and filter the values in the range.getValues() array that correspond to the first element in apps script

In the spreadsheet provided, I have compiled a list of cities in different states of my country. This information will be utilized in a form; however, it is not feasible for users to sift through an extensive list of all cities listed. Therefore, I am look ...

Tips for overlaying an image on a div regardless of its height

(!) Although this question may seem repetitive, I have not been able to find a suitable solution in any of the previous 10 topics. I apologize for the inconvenience and am actively seeking a resolution to this unique situation; Allow me to outline the iss ...

What is the best way to incorporate arrow buttons on my website in order to unveil various sections on the homepage?

A colleague and I are collaborating on a website for his cookery business. He has sketched out some design ideas on paper, one of which involves having a homepage with 4 different sections stacked on top of each other. Each section would have an arrow butt ...

Troubleshooting issue with asp.net jquery datepicker functionality

Having recently delved into the world of JavaScript and jQuery, I'm encountering some issues that I can't seem to resolve. My gut feeling is that the problem lies in the reference to the jQuery files not working properly, but I could be mistaken. ...

How can I prevent the state from being overridden in the reducer function when updating the State Context API?

I'm currently facing an issue with my reducer case where it ends up overwriting the passed id instead of simply adding to the existing array of ids. Can you enlighten me on the fundamental concept behind state copying and clarify when to utilize the s ...

The comparison between StrictNullChecks and Union Types in terms of syntax usage

Understanding StrictNullChecks in TypeScript Traditionally, null and undefined have been valid first class type citizens in JavaScript. TypeScript formerly did not enforce this, meaning you couldn't specify a variable to potentially be null or unde ...

Error message: "Unable to locate jQuery file within the node.js + Express application running on Heroku platform."

My current setup involves a node.js application with Express and express-handlebars deployed on Heroku. However, whenever I run the app, the console displays a 404 error for the jquery file, leading to subsequent failures for dependent libraries like Boots ...

Display only one field and hide the other field using a jQuery IF/ELSE statement

Hey there! I have a situation where I need to toggle between two fields - one is a text field and the other is a text_area field. When a user clicks on one field, the other should be hidden and vice versa. I've tried using JQuery for this: $(document ...

The infinite scrolling feature encounters issues when scrolling downwards

My infinite scroll code is causing a problem - it only works when scrolling up, not down. Can someone help me fix this issue? <script type="text/javascript"> $(document).ready(function(){ $(window).scroll(function(){ var lastID = $(&apos ...

What steps can I take to ensure that my bot disregards any actions taken by other bots?

I need assistance with configuring my bot to ignore certain actions by other bots and prevent logging them. Below is the snippet of my code: let messagechannel = oldMember.guild.channels.find(r => r.name === config.logsChannel); if (!messagecha ...