Sign in to follow this  

Any point on a sphere

This topic is 4046 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, could somone point me in the right direction to calculating any point on a sphere, given the radius of the sphere. Im wanting to "plot" a sphere by looping through each point on the sphere. Regards Asheh

Share this post


Link to post
Share on other sites
Quote:
could somone point me in the right direction to calculating any point on a sphere, given the radius of the sphere.Im wanting to "plot" a sphere by looping through each point on the sphere.


Some clarity please, a sphere has <insert very very large number here> of points which lie on its surface. It sounds like you are asking how to find all the points and then plot them.

A point lies on the surface of a sphere if the magnitude of the vector between the point and the center of the sphere is equal to the spheres radius.

Share this post


Link to post
Share on other sites
Quote:
Original post by deffer
Do you mean: random point on a sphere?

Or do you want to generate a sequence of points of a sphere in some uniform manner?


the latter, yes

Share this post


Link to post
Share on other sites
Quote:
Original post by Asheh
Quote:
Original post by deffer
Do you mean: random point on a sphere?

Or do you want to generate a sequence of points of a sphere in some uniform manner?


the latter, yes


As I can see, you don't seek for plotting points, but to build a sphere from triangles. From then, you can plot only points of the triangles, or draw full-blown sphere.
A search for "sphere triangulation" gives this thread, for example.

Share this post


Link to post
Share on other sites
Let's first look at approximating a circle with some points: (In C++, though you could probably figure out any other language from this)

for(int i = 0; i < MAX_POINTS; i++)
{
float angle = i/MAX_POINTS * 2 * PI;
//Calculates the point's position
float x = cos(angle)*RADIUS;
float y = sin(angle)*RADIUS;

AddPoint(x,y);//Adds the point to your list, or plots it, or does whatever you want to do with the point
}





Okay, that's pretty simple. It just loops through MAX_POINTS number of angles in a circle and plots point RADIUS away from the origin.

Now, for a sphere, we'll start with the same code as before. However, now we have to make a new circle every loop instead of a circle. We'll achieve this with two nested loops:

for(int i = 0; i < MAX_POINTS; i++)
{
//The angle around the equator:
float xAngle = i/MAX_POINTS * PI;//Note: No longer multiply by 2

//Now create a circle that intersects
for(int j = 0; j < MAX_POINTS; j++)
{
float zAngle = j/MAX_POINTS * 2 * PI;

//Calculates the point's position
float x = cos(xAngle)*RADIUS*cos(yAngle);
float y = sin(xAngle)*RADIUS*cos(yAngle);
float z = cos(xAngle)*RADIUS*sin(yAngle);

AddPoint(x,y,z);
}
}





Notice how the first loop only loops to PI, not to 2 PI. This is because a circle also covers the part of the circle opposite from the first point, hence we only have to go half-way around. Also, I haven't tested this, and actually just 'guessed' the last half.

Hope that helps (and works)!

[Edit: changed ints to floats.]

Share this post


Link to post
Share on other sites
Quote:
//Calculates the point's position
float x = cos(xAngle)*RADIUS*cos(yAngle);
float y = sin(xAngle)*RADIUS*cos(yAngle);
float z = cos(xAngle)*RADIUS*sin(yAngle);


That should read:
float z = RADIUS*sin(yAngle);

Share this post


Link to post
Share on other sites
Ezbez's algorithm was good, but I think this one should do the trick perfectly, because I'm using the exact parametric equations given on Wikipedia.

void PlotObjectsAsSphere( ObjectArray* objects, Vector3 center, Scalar radius ){    
int n = (int)sqrt(objects->size()); // Assuming this size is a perfect square if you want it to look uniform
int i = 0; // Array iterator
int u, v; // Paramaters
float x, y, z; // Co-ordinates
// Loop for u
for( u = 0; u < n; u++ ){
float theta = (u/n-1) * PI; // 0 <= theta <= PI
// Loop for v
for( v = 0; v < n; v++ ){
float phi = (v/n-1) * PI * 2; // 0 <= phi <= 2PI
// Get Co-ordinates
x = center.x + radius * sin(theta) * cos(phi);
y = center.y + radius * sin(theta) * sin(phi);
z = center.z + radius * cos(theta);
// Plot
objects[i]->plot( x, y, z );
i++; // Next object
}
}
}



The only glitch in this algorithm I see is if the size of your ObjectArray is not a perfect square, then the distribution of objects about the sphere will be uneven.

[Edited by - Verminox on October 21, 2006 1:06:54 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Verminox
Ezbez's algorithm was good, but I think this one should do the trick perfectly, because I'm using the exact parametric equations given on Wikipedia.

void PlotObjectsAsSphere( ObjectArray* objects, Vector3 center, Scalar radius ){    
int n = (int)sqrt(objects->size()); // Assuming this size is a perfect square if you want it to look uniform
int i = 0; // Array iterator
int u, v; // Paramaters
float x, y, z; // Co-ordinates
// Loop for u
for( u = 0; u < n; u++ ){
float theta = (u/n-1) * PI; // 0 <= theta <= PI
// Loop for v
for( v = 0; v < n; v++ ){
float phi = (v/n-1) * PI * 2; // 0 <= phi <= 2PI
// Get Co-ordinates
x = center.x + radius * sin(theta) * cos(phi);
y = center.y + radius * sin(theta) * sin(phi);
z = center.z + radius * cos(theta);
// Plot
objects[i]->plot( x, y, z );
i++; // Next object
}
}
}



The only glitch in this algorithm I see is if the size of your ObjectArray is not a perfect square, then the distribution of objects about the sphere will be uneven.
It's been noted a number of times that the OP is looking for a uniform distribution, so spherical coordinates are not the correct solution.

Share this post


Link to post
Share on other sites
The best method I have come up with for generating a uniform distribution of points on a sphere is to create a diamond like shape( by placing points at (Cx,Cy,Cz+r),(Cx,Cy,Cz-r),(Cx,Cy+r,Cz),(Cx,Cy-r,Cz),(Cx+r,Cy,Cz),(Cx-r,Cy,Cz) ) and then subdivide each triangle into 4 triangles(formed by using the midpoints of the triangle edges) and then scaling all the points so they are the crrect "radius" from the center.Then repreat until you have the desired number of points. The primary disadvantages being that it is a little slow, potentially uses alot of memory(you have to hold all he previous points in memory to keep subdividing), and you can only get points in amounts of 6*2^n . However, it does give a very even distribution. I'm pretty sure this is the method used in unreal tournament since I got the idea while playing with the unreal editor.

link to applet with triangle mesh spheres made using this method:
http://alrecenk.cjb.net:81/Java/show/mesh/
(rotates using arrow keys)


edit: The link deffer gave talks more about the method I was trying to decribe....maybe I should start reading all the linked material before I post?...nah...

Share this post


Link to post
Share on other sites
A diamond like distribution is not uniform, and neither are the spherical coordinate distributions, nor the "normalize a random vector" distribution.

The simplest uniform distribution is to parameterize the unit sphere over Z (height) from -1 to 1 using equal linear distance, and Phi (circumference) from -Pi to Pi using equal angular distance. This will give a uniform distribution (check the integral if you don't believe me!). Then plot the center of each discrete wedge.

For example:


for (float Z = -1; Z < 1; Z += 0.125f) {
// find the center of the slice
float Zb = Z + (0.125f / 2);
for (float Phi = -Pi; Phi < Pi; Phi += 0.25f) {
// find the center of the arc
float Pb = Phi + (0.25f / 2);
// create a point at the center of the wedge
Point = Point(sin(Pb) * sqrt(1 - Zb*Zb), cos(Pb) * sqrt(1 - Zb*Zb), Zb);
}
}


Or, to create a uniformly distributed random scattering of points on the sphere, generate random Z and Phi (each using linear distribution), and calculate the point. For that, you don't need to find the center of the "bands" because the bands are, effectively, infinitely thin.

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
The simplest uniform distribution is to parameterize the unit sphere over Z (height) from -1 to 1 using equal linear distance, and Phi (circumference) from -Pi to Pi using equal angular distance. This will give a uniform distribution (check the integral if you don't believe me!). Then plot the center of each discrete wedge.
It may be uniform in the one sense, but it doesn't give spherical symmetry, and will give greater variance of the distance between points than say a geodesically expanded icosahedron.
For more information, you may wish to read about golf ball dimples.

I certainly prefer starting with an icosahedron.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ezbez
float angle = i/MAX_POINTS * 2 * PI;

angle will always be zero, because i is smaller than MAX_POINTS and you are doing integer division.

Share this post


Link to post
Share on other sites

This topic is 4046 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this