1

I’m creating random x,y,z points on a sphere for a background I’m making. I first tried rectangular coordinates created from spherical coordinates by making angles phi (0,2pi) and theta (0,pi) uniformly random. I thought I noticed some clustering in my simulation on the z axis. I wrote some python to test it and my points are not uniformly distributed.

My next guess (with looking up anything) was to make every call to phi and theta a new random angle. This was a bad guess. It should have been obvious that the magnitudes would be different and points would not land on the sphere. It did create a cube like distribution with a neat plus sign when looking down on it.

Looking it up, I found that creating normalized rectangular coordinates from a gaussian distribution does in fact make a uniformly random sphere! I also read this is common knowledge for people who deal with probability. Reading “a multivariate standard normal distribution is spherically symmetric”. I have a very basic understanding of probability so that sentence doesn't mean much to me.

Is there an intuitive explanation for this?

import matplotlib.pyplot as plt
import numpy as np

pi = np.pi tau = 2*np.pi r = 1 n = 10

def randUniform(r,n): theta = np.random.uniform(0,1,size=n)pi phi = np.random.uniform(0,1,size=n)tau return rnp.array([np.sin(theta)np.cos(phi),np.sin(theta)*np.sin(phi),np.cos(theta)]).T

def moreRandUniform(r,n): theta = np.random.uniform(0,1,size=(n,3))pi phi = np.random.uniform(0,1,size=(n,3))tau return rnp.array([np.sin(theta[:,0])np.cos(phi[:,0]),np.sin(theta[:,1])*np.sin(phi[:,1]),np.cos(theta[:,2])]).T

def randGauss(r,n): xyz = np.random.normal(0, 1, size=(n,3)) return r * xyz / np.outer(np.sqrt(np.sum(xyz**2,axis=1)),[1,1,1])

fig = plt.figure(0) ax = fig.add_subplot(projection='3d') points = randUniform(1,5000) print(f'avg mag {np.mean(np.sqrt(np.sum(points**2,axis=1)))}') ax.scatter(points[:,0], points[:,1], points[:,2], s=.1, label='random phi & theta') ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') ax.legend()

fig = plt.figure(1) ax = fig.add_subplot(projection='3d') points = moreRandUniform(1,10000) print(f'avg mag {np.mean(np.sqrt(np.sum(points**2,axis=1)))}') ax.scatter(points[:,0], points[:,1], points[:,2], s=.1, label='more random phi & theta') ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') ax.legend()

fig = plt.figure(3) ax = fig.add_subplot(projection='3d') points = randGauss(1,5000) print(f'avg mag {np.mean(np.sqrt(np.sum(points**2,axis=1)))}') ax.scatter(points[:,0], points[:,1], points[:,2], s=.1, label='gaussian xyz') ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') ax.legend()

first try

second try

third try

cj91
  • 45

0 Answers0