Search code examples
c++geometrygeodesic-sphere

Determining texture co-ordinates across a geodesic sphere


I've generated a geodesic sphere for opengl rendering following a question on here and I'm trying to put texture on it. I came up with the following code by reversing an algorithm for a point on a sphere:

//complete circle equation is as follows
///<Summary>
///x = r * sin(s) * sin(t)
///y = r* cos(t)
///z = r * cos(s) * sin(t)
///</Summary>


float radius = 1.0f;

//T (height/latitude) angle
float angleT =  acos(point.y / radius) ;

//S (longitude )angle
float angleS = ( asin(point.x / (radius * sin(angleT)))) + (1.0f* M_PI);
float angleS2 =( acos(point.z / (radius * sin(angleT)))) + (1.0f * M_PI);

//Angle can be 0-PI (0-180 degs), divide by this to get 0-1
angleT = angleT / (M_PI);

//Angle can be 0-2PI (0-360 degs)S
angleS = angleS / ( M_PI *2 );
angleS2 = angleS2 / ( M_PI *2 );

//Flip the y co-ord
float yTex = 1 - angleT;
float xTex = 0.0f;

//I have found that angleS2 is valid 0.5-1.0, and angleS is valid (0.3-0.5)
if (angleS < 0.5f)
{
    xTex = angleS;
}
else
{
    xTex = angleS2;
}

return glm::vec2( xTex , yTex);

As you can see, I've found that both versions of calculating the S angle have limited valid ranges.

float angleS = ( asin(point.x / (radius * sin(angleT)))) + (1.0f* M_PI);
float angleS2 =( acos(point.z / (radius * sin(angleT)))) + (1.0f * M_PI);

S1 is gives valid answers between x texture co-ords 0.3 and 0.5 and S2 gives valid answers for between x texture co-ords 0.5 and 1.0 (Conversion to co-ords omitted above but present in first code example). Why is it that neither formula is giving me valid answers for under 0.3?

Thanks

Will

Correct on this side Correct on this side The weird border between working and not, probably caused by opengl's interpolation The weird border between working and not, probably caused by opengl's interpolation Reversed section Reversed section The image being used The image being used Edit: Here is the seam Seam


Solution

  • The equations you use to calculate the longitude angles are not correct seeing what you are trying to accomplish. For the longitude angle, the range you require is 0-360 degrees, which can not be obtained through asin or acos functions, because those functions only return results between -90 and 90 degrees or 0 to 180 degrees. You can, however, use the atan2 function, which returns values from the correct interval. The code I've been working with for the past 2 years is the following:

    float longitude = atan2f(point.x, point.z) + (float)M_PI;
    

    This equation will map the horizontal center of the texture in the direction of positive Z axis. If you want the horizontal center of the texture to be in the direction of positive X axis, add M_PI / 2.0.