clicking on a sphere

2019-02-15 08:48发布

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?

enter image description here

2条回答
孤傲高冷的网名
2楼-- · 2019-02-15 09:36

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.

Latitude/longitude grid

See this picture's latitude/longitude grid, but apply it much denser. For each grid cell, you need 2 triangles.

查看更多
可以哭但决不认输i
3楼-- · 2019-02-15 09:37

Given:

  • the height and width of the monitor
  • the radius of the projected circle, in pixels
  • the coordinates of the point the user clicked on

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.

查看更多
登录 后发表回答