How to map a plane to a 3d sphere?

Started by
10 comments, last by legolas558 18 years ago
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
Advertisement
The first thought that comes to mind is an inverse stereographic projection, although there might be other easier mappings.
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) )
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.
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 someusername
Of 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.
Quote:Original post by legolas558
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) )


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.
Quote:Original post by someusername
Consider 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 :(
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();   }}
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 legolas558
In 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?
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.

This topic is closed to new replies.

Advertisement