Having fun with D3 geo orthographic projection to build an interactive globe, based on all the great examples I found.
You can see my simple mockup at http://bl.ocks.org/patricksurry/5721459
I want the user to manipulate the globe like a trackball (http://www.opengl.org/wiki/Trackball). I started with one of Mike's examples (http://mbostock.github.io/d3/talk/20111018/azimuthal.html), and improved slightly to use canvas coordinates and express the mouse locations in 'trackball coordinates' (i.e. rotation around canvas horizontal and vertical axes) so that a fixed mouse movement gives more rotation near the edges of the globe (and works outside the globe if you use the hyberbolic extension explained above), rather than Mike's one:one correspondence.
It works nicely when the globe starts at an unrotated position (north pole vertical), but when the globe is already rotated (manipulate the example so the north pole is facing out of the page) then the trackball controls become non-intuitive because you can't simply express a change in trackball coordinates as a delta in the d3.geo.rotate lat/lon coordinates. D3's 3-axis rotation involves applying a longitude rotation (spin around north pole), then a latitude rotation (spin around a horizontal axis in the canvas plane), and then a 'yaw' rotation (spin around an axis perpendicular to the plane) - see http://bl.ocks.org/mbostock/4282586.
I guess what I need is a method for composing my two rotation matrices (the one currently in the projection, with a new one to rotate the trackball slightly), but I can't see a way to do that in D3, other than digging into the source (https://github.com/mbostock/d3/blob/master/src/geo/rotation.js) and trying to do the math to define the rotation matrix. The code looks elegant but comment-free and I'm not sure I can correctly decipher the closures with the orthographic projection instance.
On the last point, if someone knows the rotation matrix form of d3.geo.projection that would probably solve my problem too.
Any ideas?
There is an alternative solution to patricksurry's answer, by using quaternion representations, as inspired by Jason Davies. I, too, thought D3 would've already supported this composition natively! And hoped Jason Davies posted his code...
Took sometime to figure out the math. A demo is uploaded here, with an attempt to explain the math too. http://bl.ocks.org/ivyywang/7c94cb5a3accd9913263
With my limited math knowledge, I think, one of the advantages quaternion over Euler is the ability to compound multiple rotations over and over, without worrying about coordinate references. So it would always work, no matter where your north pole faces, and no matter how many rotations you'll have. (Someone please correct me, if I got this wrong).
I decided that solving for the combined rotation matrix might not be so hard. I got http://sagemath.org to do most of the hard work, so that I could express the composition of the original projection rotate() orientation plus a trackball rotation as a single equivalent rotate().
This gives much more natural behavior regardless of the orientation of the globe.
I updated the mockup so that it has the improved version - see http://bl.ocks.org/patricksurry/5721459
The sources are at http://bl.ocks.org/patricksurry/5721459 which include an explanation of the math - cool that you can use proper greek letters in javascript for almost readable math sourcecode!
It would still be good if D3 supported composition of rotate operations natively (or maybe it does already?!)
来源:https://stackoverflow.com/questions/16964993/compose-two-rotations-in-d3-geo-projection