Saturday, August 27, 2016

A simple digital globe


I mentioned in an earlier post that I'd come back to the topic of image mapping, and how to use a small bit of spherical trigonometry to place a map or photo onto a sphere.  For that purpose, I've written a small C# / WPF application to demonstrate the concept and serve as a springboard for some additional investigation.

Alas, I've also clearly got a bug somewhere, as that is supposed to be a view of North and South America, but all the images are reversed horizontally.  It is neat looking.  I'm going to finish working out a few more kinks before I post the final code and have a more in depth treatment of the subject.

Background is a Hubble image from NASA, world map on the globe is from Wikipedia.

For now, here's that bit of spherical trigonometry for converting three-dimensional Cartesian coordinates for points on the sphere to latitude and longitude. Because the sphere isn't really a sphere, but a mesh of triangles approximating a sphere.  In order to map the image onto the triangle, texture (UV) coordinates indicating relative positions on the image are employed.  To get the UV coordinates, the latitude and longitude are normalized by dividing by pi and 2 pi respectively.  There's no guarantee this is quite right - my bug may in fact lie in this code - but clearly it mostly works, or the image you see above wouldn't look right.

        private Point GetSphereUV(Point3D center, double radius, Point3D point)
        {
            Point3D effectivePoint = (Point3D)(point - center);
            double lat = Math.Acos(effectivePoint.Y / radius); //theta
            double lon = Math.Atan2(effectivePoint.Z, effectivePoint.X); //phi
            if (lon < 0)
                lon += twoPI;
            double v = lat / Math.PI;
            double u = lon / twoPI;
            return new Point(u, v);
        }



Same NASA Hubble background as before, this time with the output from one of my terrain generation experiments

No comments:

Post a Comment