Evenly distributing n points on a sphere
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Hypnotic Puzzle2
--
Chapters
00:00 Evenly Distributing N Points On A Sphere
01:23 Accepted Answer Score 17
02:57 Answer 2 Score 92
04:24 Answer 3 Score 234
05:05 Answer 4 Score 13
06:49 Thank you
--
Full question
https://stackoverflow.com/questions/9600...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #algorithm #math #geometry #uniform
#avk47
ANSWER 1
Score 234
The Fibonacci sphere algorithm is great for this. It is fast and gives results that at a glance will easily fool the human eye. You can see an example done with processing which will show the result over time as points are added. Here's another great interactive example made by @gman. And here's a simple implementation in python.
import math
def fibonacci_sphere(samples=1000):
    points = []
    phi = math.pi * (math.sqrt(5.) - 1.)  # golden angle in radians
    for i in range(samples):
        y = 1 - (i / float(samples - 1)) * 2  # y goes from 1 to -1
        radius = math.sqrt(1 - y * y)  # radius at y
        theta = phi * i  # golden angle increment
        x = math.cos(theta) * radius
        z = math.sin(theta) * radius
        points.append((x, y, z))
    return points
1000 samples gives you this:

ANSWER 2
Score 92
This is known as packing points on a sphere, and there is no (known) general, perfect solution. However, there are plenty of imperfect solutions. The three most popular seem to be:
- Create a simulation. Treat each point as an electron constrained to a sphere, then run a simulation for a certain number of steps. The electrons' repulsion will naturally tend the system to a more stable state, where the points are about as far away from each other as they can get.
 - Hypercube rejection.  This fancy-sounding method is actually really simple:  you uniformly choose points (much more than 
nof them) inside of the cube surrounding the sphere, then reject the points outside of the sphere. Treat the remaining points as vectors, and normalize them. These are your "samples" - choosenof them using some method (randomly, greedy, etc). - Spiral approximations. You trace a spiral around a sphere, and evenly-distribute the points around the spiral. Because of the mathematics involved, these are more complicated to understand than the simulation, but much faster (and probably involving less code). The most popular seems to be by Saff, et al.
 
A lot more information about this problem can be found here
ACCEPTED ANSWER
Score 17
In this example code node[k] is just the kth node. You are generating an array N points and node[k] is the kth (from 0 to N-1). If that is all that is confusing you, hopefully you can use that now.
(in other words, k is an array of size N that is defined before the code fragment starts, and which contains a list of the points).
Alternatively, building on the other answer here (and using Python):
> cat ll.py
from math import asin
nx = 4; ny = 5
for x in range(nx):
    lon = 360 * ((x+0.5) / nx)
    for y in range(ny):                                                         
        midpt = (y+0.5) / ny                                                    
        lat = 180 * asin(2*((y+0.5)/ny-0.5))                                    
        print lon,lat                                                           
> python2.7 ll.py                                                      
45.0 -166.91313924                                                              
45.0 -74.0730322921                                                             
45.0 0.0                                                                        
45.0 74.0730322921                                                              
45.0 166.91313924                                                               
135.0 -166.91313924                                                             
135.0 -74.0730322921                                                            
135.0 0.0                                                                       
135.0 74.0730322921                                                             
135.0 166.91313924                                                              
225.0 -166.91313924                                                             
225.0 -74.0730322921                                                            
225.0 0.0                                                                       
225.0 74.0730322921                                                             
225.0 166.91313924
315.0 -166.91313924
315.0 -74.0730322921
315.0 0.0
315.0 74.0730322921
315.0 166.91313924
If you plot that, you'll see that the vertical spacing is larger near the poles so that each point is situated in about the same total area of space (near the poles there's less space "horizontally", so it gives more "vertically").
This isn't the same as all points having about the same distance to their neighbours (which is what I think your links are talking about), but it may be sufficient for what you want and improves on simply making a uniform lat/lon grid.
ANSWER 4
Score 13
What you are looking for is called a spherical covering. The spherical covering problem is very hard and solutions are unknown except for small numbers of points. One thing that is known for sure is that given n points on a sphere, there always exist two points of distance d = (4-csc^2(\pi n/6(n-2)))^(1/2) or closer.
If you want a probabilistic method for generating points uniformly distributed on a sphere, it's easy: generate points in space uniformly by Gaussian distribution (it's built into Java, not hard to find the code for other languages). So in 3-dimensional space, you need something like
Random r = new Random();
double[] p = { r.nextGaussian(), r.nextGaussian(), r.nextGaussian() };
Then project the point onto the sphere by normalizing its distance from the origin
double norm = Math.sqrt( (p[0])^2 + (p[1])^2 + (p[2])^2 ); 
double[] sphereRandomPoint = { p[0]/norm, p[1]/norm, p[2]/norm };
The Gaussian distribution in n dimensions is spherically symmetric so the projection onto the sphere is uniform.
Of course, there's no guarantee that the distance between any two points in a collection of uniformly generated points will be bounded below, so you can use rejection to enforce any such conditions that you might have: probably it's best to generate the whole collection and then reject the whole collection if necessary. (Or use "early rejection" to reject the whole collection you've generated so far; just don't keep some points and drop others.) You can use the formula for d given above, minus some slack, to determine the min distance between points below which you will reject a set of points. You'll have to calculate n choose 2 distances, and the probability of rejection will depend on the slack; it's hard to say how, so run a simulation to get a feel for the relevant statistics.