I have a center vector (x,y,z).
I want to generate N random points that lies outside the border of a sphere with radius r and center x,z,y and inside a sphere with radius 2*r and center x,y,z.
I have implemented this via the following
function generatePointFromCenter(center, radiusStart, radiusEnd) {
var d, x, y, z;
var scaleThreshold = radiusStart/radiusEnd;
do {
x = Math.random() * 2.0 - 1.0;
y = Math.random() * 2.0 - 1.0;
z = Math.random() * 2.0 - 1.0;
d = x * x + y * y + z * z;
} while (d > 1.0 || d < scaleThreshold);
return new THREE.Vector3(x, y, z).multiplyScalar(radiusEnd)
}
Needless to say, this approach is very slow if the scaleThreshhold is close to 1.0, because the while loop has to be run so many times.
Is there a faster way to generate the points?
UPDATE: The following code seems to do the trick. I'm not sure if I should use the cubic root to prevent cluttering but it seems to work. From another example " Curves are modeled by trigonometric functions, which have distinct curved areas which vary differently with respect to the input. In a later method, we tackle this problem by using the cubic root"
var u = Math.random();
var v = Math.random();
var theta = u * 2.0 * Math.PI;
var phi = Math.acos(2.0 * v - 1.0);
var number = Math.random() * (radiusEnd - radiusStart) + radiusStart;
var r = number;
var sinTheta = Math.sin(theta);
var cosTheta = Math.cos(theta);
var sinPhi = Math.sin(phi);
var cosPhi = Math.cos(phi);
var x = r * sinPhi * cosTheta;
var y = r * sinPhi * sinTheta;
var z = r * cosPhi;
return new THREE.Vector3(x, y, z);

The easiest way would be to use spherical coordinates: Let $\tilde{r}$ be a random value in $[r,2r]$, and $\theta \in [0,\pi]$, $\psi \in [0,2\pi)$, and then convert back to Cartesian coordinates.