# How to map a plane to a 3d sphere?

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

## Recommended Posts

I have an array of vertices (x, y, z) of a 3d terrain on a plane. How can I map them to an array of vertices on a sphere surface? I fear the answer being in my fat math books... :( P.S. I need the 3d sphere rendering only for an overview of the planet, like in UFO, no high details are needed

##### Share on other sites
The first thought that comes to mind is an inverse stereographic projection, although there might be other easier mappings.

##### Share on other sites
Thank you!

Can you please tell me if the following formula takes in account the height of mountains (upper case Z of the first set)?

R := R0 + Z

(X,Y,Z) -> (x,y,z) = ( 2X/(R^2 + 1), 2Y/(R^2 + 1), (R^2 - 1)/(R^2 + 1) )

##### Share on other sites
Another simple way would be to map the entire x range to the longitude, the y range to the latitude, and simply use their z to extrude vertices above the surface of the "planet".

If the vertices' X & Y are in the range {xmin, xmax} and {ymin, ymax} respectively, what you want is:
φ = 2π*(x - xmin)/(xmax - xmin)θ = -π/2 + π*(y - ymin)/(ymax - ymin)r = r0 + zx' = x0 + r*cos(φ)*cos(θ)y' = y0 + r*sin(φ)*cos(θ)z' = z0 + r*sin(θ)

x0, y0, z0 are the center of the planet and r0 its desired initial radius.
(x',y',z') will be the cartesian coordinates of the point on the sphere.
Of course, there will be visible "seams" along the lines y = ymax and x = xmax if your terrain doesn't "tile" in these directions.

##### Share on other sites
Mmmh..looks like I am wrong about that function then.

Can you please tell me if it is correct?

I would better like a function composed without sinusoidal functions, however I may reduce it to a non-sinusoidal one with a bit of paper, ink and patience ;)

Quote:
 Original post by someusernameOf course, there will be visible "seams" along the lines y = ymax and x = xmax if your terrain doesn't "tile" in these directions.

This is not important, I just need a small rotating planet view. I may also pre-render a colored texture for the heights and apply it to the whole surface.

##### Share on other sites
Quote:
 Original post by legolas558Thank you!Can you please tell me if the following formula takes in account the height of mountains (upper case Z of the first set)?R := R0 + Z(X,Y,Z) -> (x,y,z) = ( 2X/(R^2 + 1), 2Y/(R^2 + 1), (R^2 - 1)/(R^2 + 1) )

I'm not 100% sure since I haven't ever tried this, but it looks to me, like it doesn't map a plane into a sphere.
Consider a horizontal slice of your original/planar terrain. All the points in it would have equal Z, thus the quantity R would be equal for all of them in the formula you present.
Therefore, the formula could be rewritten for them, as:
(X,Y,Z) = (c*2X, c*2Y, c*(R^2-1)) = c*(2X, 2Y, c2)

where all "c" variables are constant numbers.
Thus, the formula will merely scale their X,Y and map them onto another height. It doesn't map them on another sphere whose radius would correspond to their original height.

##### Share on other sites
Quote:
 Original post by someusernameConsider a horizontal slice of your original/planar terrain. All the points in it would have equal Z

Yes, this was the basic case. In facts I was considering the inverse of a stereographic projection (from a sphere to a 2D plane)

(x,y,z) --> (X,Y,Z) = (x/(1-z), y/(1-z),0)

In my case I have to do the inverse, and Z!=0 since I have an height value to consider. I am getting confused :(

##### Share on other sites
I will use sinusoidal functions. I would like to adapt this function by P.Bourke to have it consider my custom vertices representing a 2D plane with some heights

(source of the below code)

/*   Create a sphere centered at c, with radius r, and precision n   Draw a point for zero radius spheres*/void CreateSphere(XYZ c,double r,int n){   int i,j;   double theta1,theta2,theta3;   XYZ e,p;   if (r < 0)      r = -r;   if (n < 0)      n = -n;   if (n < 4 || r <= 0) {      glBegin(GL_POINTS);      glVertex3f(c.x,c.y,c.z);      glEnd();      return;   }   for (j=0;j<n/2;j++) {      theta1 = j * TWOPI / n - PID2;      theta2 = (j + 1) * TWOPI / n - PID2;      glBegin(GL_QUAD_STRIP);      for (i=0;i<=n;i++) {         theta3 = i * TWOPI / n;         e.x = cos(theta2) * cos(theta3);         e.y = sin(theta2);         e.z = cos(theta2) * sin(theta3);         p.x = c.x + r * e.x;         p.y = c.y + r * e.y;         p.z = c.z + r * e.z;         glNormal3f(e.x,e.y,e.z);         glTexCoord2f(i/(double)n,2*(j+1)/(double)n);         glVertex3f(p.x,p.y,p.z);         e.x = cos(theta1) * cos(theta3);         e.y = sin(theta1);         e.z = cos(theta1) * sin(theta3);         p.x = c.x + r * e.x;         p.y = c.y + r * e.y;         p.z = c.z + r * e.z;         glNormal3f(e.x,e.y,e.z);         glTexCoord2f(i/(double)n,2*j/(double)n);         glVertex3f(p.x,p.y,p.z);      }      glEnd();   }}

##### Share on other sites
It doesn't matter that it only considers a small slice of the terrain. I made this example to show that -effectively- the formula maps straight horizontal lines into straight horizontal lines at different heights.
So, it's impossible that it could ever map a plane to a sphere.

Check Mathworld's page on the stereographic projection.
It provides expressions for the longitude/latitude (inverse projection), so you can convert them directly to cartesian coordinates, just like the x',y'z' in the snippet I posted earlier.

edit:
Quote:
 Original post by legolas558In facts I was considering the inverse of a stereographic projection (from a sphere to a 2D plane)

Oh, I'm sorry, I just noticed that.
What do you want to do afterall? Turn the plane into a sphere or vice-versa?

##### Share on other sites
I want to turn a plane into a sphere. But things got a bit more complex when I wanted to use a 3d terrain instead of a completely flat plane.

I will work on a solution making some tests now.

##### Share on other sites
Quote:
 Original post by legolas558I want to turn a plane into a sphere. But things got a bit more complex when I wanted to use a 3d terrain instead of a completely flat plane.I will work on a solution making some tests now.

This is a nontrivial problem. You must sacrifice some part of the planar representation to get it to work. Which part you feel like sacrificing (e.g. distorted perspective, non-linear lines, etc.) dictates what sorts of transformations you can use.

One simple mapping is to imagine the sphere touching an infinite (flat) plane at its south pole. Call the north pole P. Choose a point on the plane, Q, to be mapped onto the sphere. Draw a line l from P to Q. This line will intersect the sphere at some point S. This point is the mapping of Q onto the sphere. To get altitude, simply note the altitude that P would have had were it not flat. Then give S the same altitude.

Hope that helps,

##### Share on other sites
Quote:
 Original post by kSquaredThis is a nontrivial problem. You must sacrifice some part of the planar representation to get it to work. Which part you feel like sacrificing (e.g. distorted perspective, non-linear lines, etc.) dictates what sorts of transformations you can use.

Since the rendered sphere will be small and a sort of preview, I am ready to make such compromises.
Quote:
 Original post by kSquaredTo get altitude, simply note the altitude that P would have had were it not flat. Then give S the same altitude.

My solution was to move the S point by its altitude following the radial versor. This is not precise, since I would have to recalculate altitude considering the new plane of the transformed vertices and keeping my peak orthogonal to it.

##### Share on other sites

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

## 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

• ### Forum Statistics

• Total Topics
628725
• Total Posts
2984407

• 25
• 11
• 10
• 16
• 14