I have a unit sphere (radius 1) that is drawn centred in orthogonal projection.
The sphere may rotate freely.
How can I determine the point on the sphere that the user clicks on?
I have a unit sphere (radius 1) that is drawn centred in orthogonal projection.
The sphere may rotate freely.
How can I determine the point on the sphere that the user clicks on?
Given:
And assuming that the top-left corner is (0,0), the x value increases as you travel to the right, and the y value increases as you travel down.
Translate the user's click point into the coordinate space of the globe.
userPoint.x -= monitor.width/2
userPoint.y -= monitor.height/2
userPoint.x /= circleRadius
userPoint.y /= circleRadius
Find the z coordinate of the point of intersection.
//solve for z
//x^2 + y^2 + z^2 = 1
//we know x and y, from userPoint
//z^2 = 1 - x^2 - y^2
x = userPoint.x
y = userPoint.y
if (x^2 + y^2 > 1){
//user clicked outside of sphere. flip out
return -1;
}
//The negative sqrt is closer to the screen than the positive one, so we prefer that.
z = -sqrt(1 - x^2 - y^2);
Now that you know the (x,y,z) point of intersection, you can find the lattitude and longitude.
Assuming that the center of the globe facing the user is 0E 0N,
longitude = 90 + toDegrees(atan2(z, x));
lattitude = toDegrees(atan2(y, sqrt(x^2 + z^2)))
If the sphere is rotated so that the 0E meridian is not directly facing the viewer, subtract the angle of rotation from the longitude.
One possible approach is to generate the sphere from triangles, consisting of rows and columns. They can be invisible too. And then hit-testing those triangles with a mouse pick ray.
See this picture's latitude/longitude grid, but apply it much denser. For each grid cell, you need 2 triangles.