Friday, March 7, 2014

How to Draw things on a Sphere

I'm working on a Processing project called "Nuclear Bundling Visualizer". Part of the project is to draw something on a geographic coordination. Turns out, it's pretty complicated!

To locate a point on the sphere:

Mr.Philipp Oehrlein wrote a good blog post about mapping data from Latitude and Longitude to points in 3D space. Here's his method for such conversion:

  private PVector toPointOnGlobe(float lat, float lng)
  {
    float _lat = radians(lat) * -1;
    float _lng = radians(lng);

    float x = radius * cos(_lat) * cos(_lng);
    float y = radius * sin(_lat) * (-1);
    float z = radius * cos(_lat) * sin(_lng);

    return new PVector(x, y, z);
  }

My teacher Joe Pietruch and I spent some time to figure out the other problem: What if I want to draw a flat object that is tangent to the sphere at such point? This would require finding out the 3D rotation that object requires.


    // #MAGICAL 3D ROTATION
    // 1. Since all discs are drawn on x and y only, suppose a vector is pointing     //    out normal to the disc (normal to the x and y plane)
    PVector discNormal = new PVector(0, 0, 1);
    // 2. Because rotate() rotates an angle around an axis (could be a vector),
    //    We need to rotate the disc on the plane the disc and a [line that 
    //    points from middle of sphere to the point on globe] forms
    PVector line = toPointOnGlobe(lat, lng);
    line.normalize();
    //    (cont. 2) and to do that, we get the vector normal to such plane using 
    //    cross()
    PVector axis = line.cross(discNormal);
    // 3. Find the angle that needs to be rotated
    float ang = PVector.angleBetween(line, discNormal);
    // 4. Rotate the flat circle on such plane, around that axis, by that amount 
    //    of degree.
    translate(v1.x, v1.y, v1.z);
    rotate(-ang, axis.x, axis.y, axis.z);

Well wasn't that a huge chunk...
[TODO] Make pretty 3D illustrations to show how it works step by step.

No comments:

Post a Comment