Reputation: 9218
In Three.js (which uses JavaScript/ WebGL), given a bigger sphere -- with a radius of say 200 -- how would I position a number of smaller objects (spheres, in my case) on random outside positions of this sphere? For instance, imagine the sphere being a world, and there are small spheres resting in random positions on the ground of this world.
Thanks!
Upvotes: 0
Views: 6562
Reputation: 19592
If it's just for a sphere I would do this:
sphere.position.x = Math.random() * 2 - 1;
sphere.position.y = Math.random() * 2 - 1;
sphere.position.z = Math.random() * 2 - 1;
sphere.position.normalize();
sphere.position.multiplyScalar( 200 );
Upvotes: 4
Reputation: 534
I made a GeometryUtils method for getting random points on a mesh, you could just use this:
https://github.com/mrdoob/three.js/blob/master/src/extras/GeometryUtils.js#L304
var points = THREE.GeometryUtils.randomPointsInGeometry( geometry, nPoints );
It's more complicated than sphere-specific solution but it will give you points that are always on the real mesh (as opposed to points being on perfect geometrical sphere, which for example if you deal with planetary sized mesh, may be off).
Another option for getting more precise points directly on the mesh would be to generate random points on a larger sphere and then raycast them toward sphere center.
Though if you don't care too much about precision, simple geometry methods should be enough.
BTW mrdoob's method is good but it should have an extra step of rejecting vectors with length > 1 (see hypercube rejection method).
http://local.wasp.uwa.edu.au/~pbourke/geometry/spherepoints/
Random Point on a given Sphere
See also here for some other methods how to generate random points on a sphere:
http://www.math.niu.edu/~rusin/known-math/96/sph.rand
Upvotes: 5
Reputation: 9218
Just thought of one solution, though perhaps not the best: getting random vertices from the larger square, and position the smaller objects at those points. Like:
var max = this.sphere.geometry.vertices.length;
for (var i = 0; i < max; i++) {
if ( Misc.getChance(5) ) {
var vertex = this.sphere.geometry.vertices[i];
var sphere = new THREE.Mesh(geometry, material);
sphere.position.set(vertex.x, vertex.y, vertex.z);
scene.add(sphere);
}
}
Putting the objects in a group, then scaling the group, will move them a bit higher above ground:
spheresGroup.scale.x = spheresGroup.scale.y = spheresGroup.scale.z = 1.05;
Possibly not a very good solution.
Upvotes: 0