What is the method for generating a random Vector3 inside a sphere?

Recently, I've been experimenting with creating a random point within a sphere. However, I seem to be struggling in getting it right. The current code I have written actually returns a point within a cube instead of a sphere. I suspect there might be something related to the Math.PI function that I'm missing out on.

  #createParticlePosition() {
    const shape = this.options.shape;
    // shape.radius = 2;
    if (shape.type === 'sphere') {
      return new Three.Vector3(
        (Math.random() * shape.radius - (shape.radius / 2)) * 1.0,
        (Math.random() * shape.radius - (shape.radius / 2)) * 1.0,
        (Math.random() * shape.radius - (shape.radius / 2)) * 1.0
      );
    }
  }

Answer №1

You are simply creating boxes at the moment. Your calculations for x,y,z values are linear, not spherical. To handle these calculations in a more spherical manner, you can make use of Three.js's built-in method called Vector3.randomDirection:

const maxRadius = 2;

// Generate random value within [0, 2]
const randomRadius = Math.random() * maxRadius;

// Create a new vector
const randomVec = new THREE.Vector3();

// Point the vector in a random direction with a radius of 1
randomVec.randomDirection();

// Adjust the vector to match the random radius
randomVec.multiplyScalar(randomRadius);

This approach uses an internal method to prevent density accumulation around the poles.

https://i.sstatic.net/0ihC4.png

Answer №2

In order to evenly distribute points within a sphere with direction and radius parameters, the equation for computing the radius is

Math.sqrt( r * r * Math.random());

The snippet showcases two point clouds - the red one using a simple formula of r * Math.random(), while the aqua one utilizes the formula mentioned above:

body{
  overflow: hidden;
  margin: 0;
}
<script type="module>
import * as THREE from "https://cdn.skypack.dev/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3a4e52485f5f7a0a140b090c">[email protected]</a>";
import {OrbitControls} from "https://cdn.skypack.dev/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="74001c06111134445a4547425a44">[email protected]</a>/examples/jsm/controls/OrbitControls";

let scene = new THREE.Scene();
scene.background = new THREE.Color(0x160016);
let camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 0, 8);
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", event => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
})

let controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.enablePan = false;

let pts = new Array(1000).fill().map(p => {
  let rMax = 2 * Math.random();
  return new THREE.Vector3().randomDirection().multiplyScalar(rMax);
})

let g = new THREE.BufferGeometry().setFromPoints(pts);
let m = new THREE.PointsMaterial({size: 0.1, color: "red"})
let p = new THREE.Points(g, m);
p.position.x = -2;
scene.add(p)

let pts2 = new Array(1000).fill().map(p => {
  let rMax = 2;
  let r = Math.sqrt(rMax * rMax * Math.random());
  return new THREE.Vector3().randomDirection().multiplyScalar(r);
})

let g2 = new THREE.BufferGeometry().setFromPoints(pts2);
let m2 = new THREE.PointsMaterial({size: 0.1, color: "aqua"})
let p2 = new THREE.Points(g2, m2);
p2.position.x = 2;
scene.add(p2)

renderer.setAnimationLoop(() => {
  controls.update();
  renderer.render(scene, camera);
});
</script>

For further reading:

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

The shared service is experiencing difficulties in transferring data to the following component

I have developed two components along with a shared service. My goal is to transfer data from one component to another, but I am encountering an issue where the object appears empty. Below is the code for the first component: import { Component, OnInit } ...

Sending data from an Ionic application to a server

I came across this solution on a forum, but it lacks detailed explanation for me to customize it according to my requirements. The author also mentions a stack overflow question, which led to various "different" solutions leaving me feeling confused. Belo ...

Maximizing the potential of a single .js file for multiple .html pages with AngularJS

I have a JavaScript file containing a function that I want to be accessible by multiple HTML pages without duplicating it in another file. Currently, the JS file starts with the following code snippet: (function(){ var app = angular.module('Proj ...

Assigning names to the points on the AxisHelper component in THREE.js

Take a look at the code snippet provided below: <html> <head> <title>My first Three.js app</title> <style>canvas { width: 100%; height: 100% }</style> </head> <body ...

Execute a website's javascript function by using Python

I've been pondering over the possibility of achieving this - Take a look at this screenshot of Chrome's "inspect element" on the current website. https://i.sstatic.net/NYSmB.jpg Is it doable for me to execute the "goCourseDetails" js function w ...

Creating a visual representation of system uptime using PHP and JavaScript by aggregating a series of heartbeats

I have multiple devices that send a signal every minute, known as a heartbeat. The timestamps of these heartbeats are stored in a MySQL table like so: +----+-----------+---------------------+ | id | entity_id | heartbeat | +----+-----------+---- ...

Launch a new window with the window.open() method and execute a function on the newly opened window

I am having trouble generating a barcode in a new window using the barcode generator script. Despite trying to use window.focus(), I can't get the barcode to appear in the new window. Any assistance on how to generate the barcode in a separate window ...

The brush functionality does not display rotated x-axis labels

I am experiencing issues with my D3 area chart that includes brush functionality on a rotated x-axis at a 45-degree angle. Initially, the x-axis labels are displayed properly but when I apply the brush to the chart, the labels disappear and do not reappe ...

Jest test failing due to issues with a stateful React component containing an asynchronous function

I'm currently going through a Jest testing tutorial on Pluralsight that can be found here. Even though I have written the code exactly like the author, my test is not passing for some reason. Link to my Pull request on the author's repo: https:/ ...

h1 tag set for jQuery AJAX activation

Currently working on a website that heavily relies on ajax. Encountering an issue that hasn't been solved through online resources. Now, I'm sharing my function for fetching a page: function loadTemplate(name, replaceWholePage = true){ $.wh ...

Interacting with various cookies created from user-provided input (specifically from textboxes) simultaneously

I'm facing a challenging problem and I'm in need of some assistance. The task at hand is to create three text boxes for users to input values for cookies named: name, city, and hobby. Then, using a single button with an onclick event, a function ...

Issue with fs.createReadStream function: it is not recognized as a valid function

I'm currently developing a project in VUE that utilizes 'fs', and I have included my code below. async Upload(file){ let fs = require('fs'); console.log(file); console.log(this.dialogImageUrl); ...

Issues with the functionality of the login page's HTML and JavaScript

Recently, I attempted to create a login page with the following code: const loginForm = document.getElementById("login-form"); const loginButton = document.getElementById("login-form-submit"); const loginErrorMsg = document.getElementById("login-error-m ...

require a global function that accesses a variable inside it

I am currently struggling with a piece of JavaScript code that is causing some difficulty for me. The code is located inside a function, and I am trying to access the soft_left and soft_top variable in other functions without much success. Below is the rel ...

Adjusting the alignment of Bootstrap navbar items upon clicking the toggle button

When I click the toggle button on a small screen, my navbar items appear below the search bar instead of aligning with the home and about elements. Below is an image depicting this issue: https://i.stack.imgur.com/4rabW.png Below is the HTML code structu ...

Maintain user authentication status in Vuex after page refresh

Hello, I have implemented a setup using Vuex and Laravel sanctum for user authentication. Below is the code snippet from my Vuex file auth.js: import axios from 'axios' export default { namespaced: true, state:{ authenticated: ...

Tips for properly formatting Sequelize association fetching in your application

I am dealing with an association many-to-many between two tables, products and orders. In the pivot table, I store the product's id, quantity, and price. However, when fetching the product, I also require the product name which can only be retrieved f ...

Issue encountered while retrieving JSON data from Github

I am currently using d3.json to retrieve a JSON link from the Enterprise GitHub (within the same repository/folder as the JavaScript file). d3.json("https://raw.github.exampleEnterprise.com/path/to/repo/data.json?token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ...

Displaying Vue.js tooltips in a table when the text gets clipped

I'm currently facing an issue with creating a tooltip in my vue.js document. I attempted to follow this guide from https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_tooltip in order to create one, but it's not working as expected. Her ...

Steps for including a URL in an ng-repeat when it is not included in the JSON object

After making a http call, I am getting a JSON object. One of the properties within this object is LinkUrl. Sometimes, LinkUrl will contain a predetermined URL from the returned object, while other times it will only have a file name. In the latter case, I ...