Sphere Click
I have a unit sphere (radius 1) that is centered on an orthographic projection.
The sphere can rotate freely.
How to determine the point on the sphere that the user clicks on?
Given:
- monitor height and width
- radius of the projected circle, in pixels
- coordinates of the point the user clicked on
And assuming the top left corner is (0,0), the x value increases as you move to the right, and the y value increases as you move down.
Move the user's click point to 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 intersection point.
//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 intersection point (x, y, z), you can find the latitude and longitude.
Assuming 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 ball spins so that the 0E meridian is not facing directly towards the viewer, subtract the angle of rotation from the longitude.
One possible approach is to create a sphere of triangles with rows and columns. They can also be invisible. And then hit testing these triangles with the mouse rays.
Check out this latitude / longitude grid, but apply a lot more tightly. For each grid cell, you need two triangles.