Philipp Lenssen
Philipp Lenssen

Reputation: 9218

Three.js: Putting smaller objects on random positions of a larger sphere

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

Answers (3)

mrdoob
mrdoob

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

alteredq
alteredq

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

Philipp Lenssen
Philipp Lenssen

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

Related Questions