Organizing points within an ellipsoidal PointCloud using Three.js

Recently, I delved into the world of Three.js, eager to experiment with its capabilities. My project involved creating an ellipsoid cloud of particles using the PointCloud object.

To achieve this, I employed the parametric equation of an ellipsoid to generate random points:

    var vertex = new THREE.Vector3();
    u = Math.random() * 2 * Math.PI;
    v = Math.random() * Math.PI;
    vertex.x = Math.random() * a * Math.cos(u) * Math.sin(v);
    vertex.y = Math.random() * b * Math.sin(u) * Math.sin(v);
    vertex.z = Math.random() * c * Math.cos(v);

Upon rendering the cloud, I noticed an unusual concentration of particles along the ellipsoid's axes. Could this be attributed to the distribution of the Math.random() function or am I overlooking something? Any insights would be greatly appreciated.

You can view the project here, and I have provided a screenshot for reference in case the visualization varies on your browser.

Edit: Following @severin-pappadeux's suggestion, I refined the code to address the uneven point distribution issue, but unfortunately, the problem persists.

Edit: In an attempt to rectify the issue, I adjusted the formula that utilizes Math.random() to define the vertices' length from:

vertex.x = Math.random() * a * wx;
vertex.y = Math.random() * b * wy;
vertex.z = Math.random() * c * wz;

to:

vertex.x = (Math.random() + 0.1) * a * wx;
vertex.y = (Math.random() + 0.1) * b * wy;
vertex.z = (Math.random() + 0.1) * c * wz;

The particles exhibited a more uniform distribution with this adjustment. Interestingly, there was no formation of a "cross-like hole" where the axes intersect, contrary to my initial expectations. While this tweak resolved my immediate concern, I remain curious about a more robust solution.

Answer №1

The distribution of angles is not uniform, as clearly seen. The observed effects are similar to those described in the following link: . One can attempt to create a vector that is uniform on a unit sphere and intersect it with an ellipse to find a vertex. Here's how you can do it:

phi   = 2.0 * Math.PI * Math.random();
csth  = 2.0 * Math.random() - 1.0;
snth  = Math.sqrt((1.0 - csth)*(1.0 + csth));
wx = snth * Math.sin(phi);
wy = snth * Math.cos(phi);
wz = csth;

The vector (wx, wy, wz) is now a unit vector. Create a ray with distance s*(wx, wy, wz). By intersecting this ray originating from (0,0,0) with an ellipse, you'll find your desired vertex.

UPDATE

I did not initially realize that the question was regarding uniformity within the given volume. To achieve uniformity within a unit sphere, one must include radius sampling as follows:

r = Math.pow( Math.random(), 1.0/3.0 ); // Alternatively, use cubic root function sqrt3()?

This will give you a point within the sphere at (r*wx, r*wy, r*wz), which can be scaled according to (a, b, c).

Answer №2

If you're looking to generate a cloud of random points that are evenly distributed within a 3D ellipsoid, here's one approach:

Start by creating random points inside a cube and filtering out any points that fall outside the enclosed sphere.

vertex.x = 2 * Math.random() - 1;
vertex.y = 2 * Math.random() - 1;
vertex.z = 2 * Math.random() - 1;
if ( vertex.length() < 1 ) geometry.vertices.push( vertex );

Once you have uniform points within a sphere, you can then scale the point cloud to form an ellipsoid.

var pointCloud = new THREE.Points( geometry, material );
pointCloud.scale.set( a, b, c );

This method utilizes three.js version r.86

Answer №3

I decided to go with @WestLangley's solution, following the advice of @Atrahasis:

while(geometry.vertices.length < 20000) {
    var vertex = new THREE.Vector3();
    vertex.x = 2 * Math.random() - 1;
    vertex.y = 2 * Math.random() - 1;
    vertex.z = 2 * Math.random() - 1;
    if(vertex.length() < 1) geometry.vertices.push(vertex);
}

To view the complete code, click here (display may be better in Firefox than Chrome).

For a bonus tip: When importing raw js files from Github to platforms like Codepen or JSFiddle, Chrome may not execute them due to the MIME type being 'text/plain'. To overcome this, replace http://raw.github.com/ with http://rawgit.com/. For example, changing

https://raw.githubusercontent.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js
to
https://rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js
worked for me!

A big thank you to @SeverinPappadeux for their valuable input.

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

What could be causing the failure of the "WebGL import" statement in my Vite project?

Here is what's happening: import { WebGL } from 'three/addons/capabilities/WebGL.js'; Details about my project setup: I initialized the root folder by using "npm create vite@latest" Executed "npm install" followed by "npm install --save t ...

Tips for managing the onloadedmetadata event

If a video file cannot be played by the browser due to format or codec issues, I want to notify the user about it. When the browser is unable to play a video (because of unsupported format or codec), the onloadedmetadata event does not occur. I have some ...

Enhance the performance of React code by refactoring it

Having recently started coding in React for a new organization, I find that the code in my component has grown lengthy and the submithandler method is causing multiple array iterations. Is there a way to refactor the code for better performance? The data t ...

Discover the following `<td>` identifier through the act of clicking on a separate `<td>` element

I have a few td's with specific ids: <td id="first">first</td> <td id="second">second</td> <td id="third">third</td> <td id="fourth">fourth</td> Whenever I click on one of the td elements, I want to re ...

"Disabling Click Event on Sidebar Menu in Angular: A Step-by-Step Guide

I am working on an Angular project with a sidebar that I want to modify in order to disable click events on the menu items. My goal is to guide users through a specific flow without allowing them to navigate freely. However, simply disabling the [routerLin ...

When copying text from React-PDF Display, the values may appear altered or varied

This snippet of text was excerpted from a brief SHA provided at the git summit. Generated using React-pdf, this is a PDF document with some interesting quirks. Although the displayed text reads as 4903677, it changes to â€ĒG07THH when copied. The font ...

Transforming a build from callback hell to promise hell

Currently, I am in the process of transitioning a complex build process filled with callbacks into using Promises (which is proving to be quite challenging due to my lack of experience with Bluebird). My main struggle lies in encountering errors when tryin ...

Acquire JSON data from a URL and display it on the webpage

I'm facing an issue where the JSON data I'm trying to fetch from a URL is not displaying due to an uncaught reference error in my code. How can I modify the code to ensure that the data gets shown? var url = "https://fantasy.premierleague.com/ ...

Unraveling the intricacies of a website template downloaded alongside a webpack ES6 project

My colleague in the office was adamant about purchasing a stunning HTML/CSS/JS external template to serve as a foundational design for our website project. This particular website is a significant endeavor that we are constructing using Laravel, SASS, and ...

JavaScript is causing performance issues in Selenium with Python

I am facing a challenge with web scraping a site that utilizes JavaScript/AJAX to load more content as you scroll down. My setup involves Python 3.7 and Selenium Chrome in headless mode. However, I've noticed that as the scraping process continues, th ...

Converting JavaScript values to C# code behind: A step-by-step guide

I'm facing a challenge where I need to retrieve JavaScript values in the code behind using C#. While I am aware that I can achieve this using hidden fields, there are no server controls on the page for postback. Can someone please advise me on how to ...

Initiate JSF ajax form using JavaScript programmatically

My aim is to execute a JSF managed bean method from within a JavaScript function. Here is the function: var fbLogin = function() { FB.login( function(response) { if (response.authResponse) { ...

Chrome browser experiencing a disappearing vertical scroll bar issue on a Bootstrap Tab

<div class="tabs-wrap left relative nomargin" id="tabs"> <ul class="nav ultab" id="fram"> <li class="active"><a href="#history" data-toggle="tab" id="history1" >History< ...

Tips for utilizing a received variable within an ejs document

I am currently attempting to update the content of an HTML element in an EJS file with a variable that I have defined in a JavaScript file. let checkbox = document.querySelector('input[name="plan"]'); checkbox.addEventListener('ch ...

Storing an object into an array within a different model

My mongoose-models are set up like this: var mongoose = require('mongoose'); var Schema = mongoose.Schema; var eventSchema = new mongoose.Schema({ name: String, date: String, dogs: [{ type: Schema.Types.ObjectId, ref: 'Dog' } ...

Encountering a problem with Selenium when dealing with tabular data displayed in a DIV format on a website, where each row is encapsulated within its own DIV element

While creating Selenium automation tests for a website with multiple rows contained within a main DIV element, each row represented by a separate DIV. For example, if there are 5 dynamically generated rows, the HTML code structure would look like this: < ...

Utilize the HTML webpack plugin to include the rendered file within the router

Hey there! I'm currently dealing with a frustrating issue. I can't seem to locate the index.html file generated by html-webpack-plugin for rendering. Even though I can access it at localhost:8080/index.html, I'm struggling to figure out how ...

In JavaScript, if a string matches a property in an array, then the array can be reordered with the

Currently, I am utilizing an Angular 5 pipe to manipulate an array before displaying it using ngFor. The array consists of all active users, and my goal is to ensure that the user who is currently logged in always appears at the beginning of the array so ...

Using JQuery datepicker() with CSS class in ASP.net for dynamically generated TemplateFields

I have implemented TemplateFields in a Gridview to dynamically create textboxes as records are added. However, due to the limitation of not being able to have ASP controls with the same ID's, using ClientIDMode=Static is not an option for these contro ...

Symfony2 compresses CSS and JS files to improve performance

Currently, I am attempting to execute php app/console assetic:dump in order to test my production environment. While my css file gets generated successfully, the js file does not. The following error message is displayed : C:\wamp\www\p ...