0
votes

I've an equirectangular projection of an image, which I load as a panoramic image where my camera is placed at origin looking at -z. My coordinate system is right handed, i.e x is on right, y is up (north) and z is coming out of screen.

What I want to do is take the selected pixel and convert it to world coordinates xyz.

The formula that I'm using to get the latitude and longitude are:

double centerX = totalWidth/2;
double centerY = totalHeight/2;

double latScaling = centerY / 90;
double lonScaling = centerX / 180;


double longitude = (pixelX-centerX)/lonScaling;
double latitude = -(pixelY-centerY)/latScaling;

totalWidth and totalHeight is the width and height of the equirectangular image and pixelX and pixelY is the selected pixel coordinates.

Further I'm using these lat/long to get the world coordinates as:

double x = sphereRadius * Math.sin(latRadians) * Math.sin(longRadians);
double y = sphereRadius * Math.cos(latRadians);
double z = sphereRadius * Math.cos(longRadians) * Math.sin(latRadians);

sphereRadius is 18 which is equal to the radius of opengl sphere on which the image is finally drawn. The camera is at the origin of this sphere. Please can somebody check if my approach is correct and if the formula's used are correct for a right handed coordinate system.

Using the above formulae I get x=0,y=18,z=0 for latitude = 0 and longitude = 0 which is not expected result. Have I missed something?

EDIT: The formula that seems to be working for me is :

//flip Y axis latRadians = Math.PI/2 - latRadians;

    double x = sphereRadius * Math.sin(latRadians) * Math.sin(longRadians);
    double y = -sphereRadius * Math.cos(latRadians);
    double z = -sphereRadius * Math.sin(latRadians) * Math.cos(longRadians);

But there's still some offset(around 850 pixels) and the deviation is minimum at equator and prime meridian, since it contains the true scale value. I think I need to calculate the offset through angles between up vector and right vector of camera. Can somebody correct me?

There's a flat equirectangular projection of which I take pixel xy position. Then this equirectangular is wrapped on the inside of sphere and my camera is at origin of this sphere. I need to calculate the world co-ordinates from pixel xy. Hope this clarifies some doubts.

1
Swap sin(lat) and cos(lat).Dietrich Epp
as per your comment my new formula is: double x = sphereRadius * Math.cos(latRadians) * Math.sin(longRadians); double y = sphereRadius * Math.cos(latRadians); double z = sphereRadius * Math.cos(longRadians) * Math.cos(latRadians); the new values are x=0,y=18,z=18 but the offset is still there, my longitude runs from West to East -180 to 180 and latitude south to north -90 to 90.Parvaz Bhaskar

1 Answers

0
votes

My approach was slightly wrong. Instead of searching for latitude longitude mapping I had to compute UV mapping of the texture. The UV mapping is slightly different from lat/long mapping. Instead of a value between -PI and PI the UV mapping is between 0.0-1.0. The texture is divided into sectors and rings. You can find the logic to generate a sphere body here

This is how I solved this problem:

generated the UV mapping from xy position of pixel

double u = pixelX/totalWidth;
double v = 1 - pixelY/totalHeight;

And used the following formula to convert to xyz coordinates of sphere

double theta = 2 * Math.PI * u; //sector
double phi = Math.PI * v; //ring

double x = Math.cos(theta) * Math.sin(phi) * sphereRadius;
double y = -Math.sin(-Math.PI/2 + phi) * sphereRadius;
double z = Math.sin(theta) * Math.sin(phi) * sphereRadius;

The sphere has poles on y axis north on +ve y and south on -ve y, where camera is at the origin of this sphere with up-vector as 0,1,0 and right vector as 1,0,0 and look-at with 0,0,-1