5

using PyPlot
n = 50
u = range(0,stop=2*π,length=n);
v = range(0,stop=π,length=n);

x = cos.(u) * sin.(v)';
y = sin.(u) * sin.(v)';
z = ones(n) * cos.(v)';

scatter3D(vec(x),vec(y),vec(z);c="red",s=1)

enter image description here

However, if I multiply vec(x), vec(y), vec(z) with rand() ,
I still get the same plot with the only difference being that the axis change or in other words that the sphere gets "squished".


using PyPlot
n = 50
u = range(0,stop=2*π,length=n);
v = range(0,stop=π,length=n);

x = cos.(u) * sin.(v)';
y = sin.(u) * sin.(v)';
z = ones(n) * cos.(v)';

scatter3D(rand()*vec(x),rand()*vec(y),rand()*vec(z);c="red",s=1)

enter image description here

  • 1
    Here you find a few good solutions, the implementation of which in python is relatively straightforward: https://math.stackexchange.com/questions/1585975/how-to-generate-random-points-on-a-sphere I personally used the "generate a 3D random point and divide by its norm" approach before and it worked great. – GPhilo Jun 22 '21 at 08:32
  • 1
    rather than generating the point through the range try generating them through random function. – Amit Gupta Jun 22 '21 at 08:34
  • Apparently my comment disappeared, so I show this again: https://stackoverflow.com/questions/33976911/generate-a-random-sample-of-points-distributed-on-the-surface-of-a-unit-sphere – Peter O. Jun 22 '21 at 09:29

1 Answers1

7

The simplest approach seems to be sampling a Gaussian for each dimension and then normalizing the length of the resulting vector as described in this answer. There's a very slight possibility of getting a vector with zero length, which can be handled with rejection sampling. Putting that together you would do this:

points = map(1:n) do _
   while true
       x = randn()
       y = randn()
       z = randn()
       l = hypot(x, y, z)
       l ≠ 0 && return (x, y, z) ./ l
    end
end

This gives a vector of 3-tuples each representing x, y and z coordinates of points, which you can plot as before. Separate vectors of coordinates can be extracted using comprehensions:

xs = [p[1] for p in points]
ys = [p[2] for p in points]
zs = [p[3] for p in points]

This approach can readily be generalized to any number of dimensions.

StefanKarpinski
  • 32,404
  • 10
  • 86
  • 111