开发者

Generating points uniformly on a sphere

I'm interested in generating points that are 'uniformly' (and non-randomly) distributed around a sphere, much like the dimples of a golf ball or the vertices of the hexagons on a soccer ball. Are there well defined algorithms to do this?

Note: I know that the points are not really 'uniformly' distributed on a sphere, but they are distributed in a way that the distribution of points looks th开发者_如何转开发e same from any direction that looks straight at any of the points - this is what I am interested in.


Subdividing an octahedron and normalizing the vertices afterwards gives very good results. Look here for more details. Paul Bourke has a lot of interesting stuff.

Here's some psuedo C++ code I wrote up in five minutes now:

/* Assume 'data' initially holds vertices for eight triangles (an octahedron) */
void GenerateSphere(float radius, std::vector<Vector3f>& data, int accum=10)
{
    assert( !(data.size() % 3) );

    std::vector<Vector3f> newData;

    for(int i=0; i<data.size(); i+=3){
        /* Tesselate each triangle into three new ones */
        Vector3f centerPoint = (data[i] + data[i+1] + data[i+2]) / 3.0f;

        /* triangle 1*/
        newData.push_back(data[i+0]);
        newData.push_back(data[i+1]);
        newData.push_back(centerPoint);
        /* triangle 2*/
        newData.push_back(data[i+1]);
        newData.push_back(data[i+2]);
        newData.push_back(centerPoint);
        /* triangle 3*/
        newData.push_back(centerPoint);
        newData.push_back(data[i+2]);
        newData.push_back(data[i+0]);
    }
    data = newData;
    if(!accum){
        /* We're done. Normalize the vertices,
             multiply by the radius and return. */
        for(int i=0; i<data.size(); ++i){
            data[i].normalize();
            data[i] *= radius;
        }
    } else {
        /* Decrease recursion counter and iterate again */
        GenerateSphere(radius, data, accum-1);
    }
    return;
}

This code will work with any polyhedron made of counter-clockwise triangles, but octahedrons are best.


Choose u,v randomly from [0,1]. 2πu is longitude. asin(2v-1) is latitude. Only two random variables, and no rejections.

By the way, my link collection has a new address: http://bendwavy.org/sphere.htm

And I've copied it over to http://cgafaq.info/wiki/Evenly_distributed_points_on_sphere


While this article talks about randomly picking points on a sphere, it is also about drawing points from a uniform distribution while at the same time taking the sphere characteristic into consideration. I guess it's still a decent read for your question:

http://mathworld.wolfram.com/SpherePointPicking.html


depending on your needs http://iquilezles.untergrund.net/www/articles/patchedsphere/patchedsphere.htm may work well too. not exactly uniform, but very fast to compute.


Here's a simple way to do it.

  1. Randomly, sample from the unit cube, [0, 1]^3

  2. Test for inclusion in the sphere. Reject if the sampled point is not in the sphere of diameter 1 that is contained in the unit cube, and go to step 1.

  3. Normalize the point to be on the surface of the sphere, by projecting the point outward from the center of the sphere.

This will typically succeed after a few samples. If you want, you can also reject samples that are near the center of the sphere to minimize rounding errors and help make the distribution closer to uniform.


if you're okay with having only certain allowable numbers of vertices, then the subdivision methods above are definitely the way to go. if you want an arbitrarily-specified number of vertices, then i recommend:

first, distribute points randomly and uniformly over the sphere. i talk at length about doing this at http://elenzil.com/progs/randompoints . i believe my method is at least as performant as that at worlfram.

second, "relax" the distribution by treating the points as a particle system where each particle repels every other particle. the difficulty here is making sure the system doesn't become unstable, and deciding when to stop. i have an example of this here: http://elenzil.com/progs/separate unfortunately these were the days before i included source code with my projects, so that code is lost.


I tried once the following algorithm:

  • start with a regular tetrahedron with the submits on the sphere.
  • pick one of the triangles with the biggest surface (initially it will be any of the 4 sides)
  • replace selected face with a 3 sided pyramid where the 4th point is the elevation of the face center to the sphere surface.
  • repeat until enough points have been created.

This works as long as precision does not ruin uniformity. The resulting points form figures akin to a geode.

You don't need to compute any surface, since each new triangle is no greater than all previous ones. Simply handle them in FIFO order.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜