3

I have a sphere in 3D. At runtime i'm generating a dynamic 2048x1024 texture for it. On this texture a tiny circle is drawn, which could be anywhere. I have the x/y of this circle on the texture, and consequently the corresponding UV coordinates. Now, i'd like to interpolate where exactly on my sphere this little circle is located.

This is the code I've been using, but it always seems to be off by +/-90 degrees

// U, V are original UV obtained from dynamic texture.

_u =  Math.PI * U;  
_v =  -2 * Math.PI * V;

_x = Math.cos(_u) * Math.sin(_v) * radius;
_y = Math.sin(_u) * Math.sin(_v) * radius;
_z = Math.cos(_v) * radius;

Thanks for any help!

user1118321
  • 25,567
  • 4
  • 55
  • 86
Brad
  • 31
  • 1
  • 1
  • 2

3 Answers3

3

According to the code you posted in the comments, here is how to generate the X, Y and Z values.

theta = 2 * PI * U;
phi = PI * V;

_x = Math.cos(theta) * Math.sin(phi) * radius;
_y = Math.sin(theta) * Math.sin(phi) * radius;
_z = -Math.cos(phi) * radius;

OLD ANSWER:

Your code is fine. Are you sure that the sphere is generated the same way, and that the poles are along the Z-axis like that? "Usually" spheres are generated with the poles along the Y-axis. Check this.

Otherwise, if you are always off by +/- 90°, play around with the sin and cos defining x and y. For example:

_x = -Math.sin(_u) * Math.sin(_v) * radius;
_y = Math.cos(_u) * Math.sin(_v) * radius;

Is a 90° rotation of the original.

There are 8 different ways you can do the sin/cos of these two components with varying signs. Without knowing how your sphere is generated, you'd have to try them all out. They go

(x = sin(u), y = cos(u));
(x = sin(u), y = -cos(u));
(x = -sin(u), y = cos(u));
(x = -sin(u), y = -cos(u));

(x = cos(u), y = sin(u));
(x = cos(u), y = -sin(u));
(x = -cos(u), y = sin(u));
(x = -cos(u), y = -sin(u));

However this is painful and hacky, I would strongly suggest trying to find out how your sphere is generated. They usually generate x, y, z positions by looping through U and V.

Hannesh
  • 7,256
  • 7
  • 46
  • 80
  • Thanks for this - the poles are on the Y-axis (Y-UP too), if that changes anything. – Brad Oct 20 '11 at 19:03
  • I'm afraid that still didn't get it :( – Brad Oct 20 '11 at 22:03
  • There are a lot of ways to map UV coords onto a sphere, it depends on how your sphere is generated. Where does your sphere come from? Are you using OpenGL or DirectX? – Hannesh Oct 21 '11 at 11:53
  • here is how the UVs are being generated (sorry about the lack of proper spacing): numUvs = 0; for (j = 0; j <= _segmentsH; ++j) { for (i = 0; i <= _segmentsW; ++i) { uvData[numUvs++] = i / _segmentsW; uvData[numUvs++] = j / _segmentsH; } } – Brad Oct 24 '11 at 16:41
  • That doesn't help much. If you post your entire sphere generation code, I can virtually guarantee you the correct algorithm ;). Just edit your question again and add the sphere generation code. – Hannesh Oct 24 '11 at 18:53
  • https://github.com/away3d/away3d-core-fp11/blob/master/src/away3d/primitives/Sphere.as that's the class generating the sphere. – Brad Oct 24 '11 at 22:20
  • Sorry about the delay, I've updated my answer. Let me know if this works. – Hannesh Oct 30 '11 at 22:16
0

The equation your using to generate the sphere is treating the pole as the Z axis. If your using something like GLUT the default coordinate system has Z plus normal to the screen with "Up" being the Y axis. If you swap the Z and the Y it may work for you. I just got finished doing something similar and I was happy with the results.

I used the following.

double theta = ((2 * PI) / lWidth) * u;
double phi = (PI / lHeight) * v;

double dX = std::cos(theta) * std::sin(phi) * radius;
double dZ = std::sin(theta) * std::sin(phi) * radius;
double dY = std::cos(phi) * radius;

The lWidth and lHeight are the dimensions of a bitmap I was mapping to the sphere.

Lynxdom
  • 1
  • 1
0

Make sure you have the proper axes defined ie :

ENU - east north up NED - North east down

The transform is different for NED and ENU usually because azimuth angle is defined the same way ie clockwise with respect to north ..

do a 90- on the theta in each or use the co-angle rule.

Try deriving the formulas yourself is possible.. make sure you know what conventions are being used

Yugi
  • 1