I know you all come here to read about why you need to save the lemurs and the many ways in which the world has tried, and failed, to murder me, but I like to think those are only two of three vital ingredients. Today I’d like to talk about my other, other raison d’etre: sweet, delicious science.
If you’ve been around one of these iPod phone things the kids are into, you know the interface is chock full of sweet, widget-like flippery. For example, the Google Maps application flips left and right when you switch between the map and list views. Spend some time staring at that effect, then try going back to Dashboard, and you’ll suddenly feel all gross and Tigery.
The widget flip is pretty simple — a quick rotation around the Y axis. It looks very normal and natural, but it would never work on the iPhone. To see why, pick up a book, such as, oh, I don’t know, “Mac OS X Leopard: Beyond the Manual.” Hold it up to your head and spin it along its Y axis. Do you see it? Look closer. Keep spinning it. Keep looking closer. Closer. Clos–ow! I’ve smacked myself in the face.
That’s because when something rotates around the Y axis, it moves toward you. In the boring, 2D world of computer graphics, we have to fake this effect using a little trick from the Renaissance period called “perspective distortion.” That is to say, we make one side all big and the other side all small and your brain goes, oh, that must mean the big side is closer to me and, voila, a decent facsimile of 3 dimensions at a significant savings to Apple.
There are two things that can ruin this effect and, by extension, your entire computer-using experience. The first is using the wrong book. Try spinning David Pogue’s significantly more popular “Mac OS X Leopard: The Missing Manual” and you don’t get 3D at all. It looks totally unrealistic. Maybe if someone spent a little less time composing witty songs for his buddies at TED and a little more time saving lemurs...
The other big downer is when you try to fake 3D by making one side of your object bigger and you run out of space and cut off the corners. Nothing says not a moon a space station like clipped corners or blowing up Alderan. Luckily something like a widget literally floats on a nearly endless sea of pixels. Even on my MacBook Pro I can only just make out the edges of the massive screen. Unfortunately, there’s no way of knowing how many pixels that is, but it’s at least 20 billion.
The iPhone is another story. The viewport is quite small, which necessitates going full-screen at all times. Without the wiggle room to make one side all big, the iPhone would be incapable of displaying any kind of decent flip and the whole device would become 2D, or worse: 1D. Do you know how easy it is to lose a 1-dimensional object? Pretty damned easy.
If you pay attention to the iPhone’s flipping animation, you’ll notice that rather than rotating around the central Y axis with the one big side and the one little side, the screen seems to rotate back from the side itself, which then slides over as if on rails, flipping itself in the process. It’s pretty damned mesmerizing, and also pretty damned hard to duplicate.
Luckily I used to work with this insane genius named Lucas, who discovered that if you put a very small value into “m34” of Core Animation’s CATranform3D struct, then scale the layer just right, you get a decent facsimile of the iPhone flip.
Since m34 doesn’t sound very good in conversation, I think of this as the “Newman factor.” The resulting distortion is, therefore, “Newman distortion,” and the units in which is it adjusted are Newmans. One Newman is equal to the inverse of the distortion, which I’m pretty sure is math-speak for transform.m34 = 1 / distortionInNewmans. In other words, the more Newmans you have, the less the distortion.
Now we just need the numbers
Someone once said an ounce of math is worth a pound of engineering. I think that’s ridiculous; if anything, math would be measured in SI units. Regardless of that, it is in the spirit of that statement I present you with approximately 3 kilograms of engineering.
In other words, because I don’t know math, I devised an engineering solution in the form of a test harness that slows down the animation, takes frame grabs, then finds and tracks the movement of the origin, paying close attention to how many pixels it moves above or below the baseline. This gives you a nice visual representation of what’s happening, as well as some hard numbers.
You can then plug in different numbers for the Newman factor and the scale until you find something that looks good. For example, here are some screenshots using a 300 x 400 pixel layer:
Here is a simple Y rotation without Newman distortion. Not very satisfying, but at least there’s no Y deviation.
Bumping distortion up to 2500 Newmans gives us a nice gentle curve, with a Y deviation of -13. Not too shabby.
Scaling down to 0.94 bring it in to a Y distortion of -3. That’s about as good as it gets at this Newman factor.
This shot demonstrates an unfortunate effect of this set of transforms, which is that, for a given Newman factor, the “right” scale doesn’t actually resolve to being flat, but rather, distorts in both directions of Y. For example, at 500 Newmans with a scale of 0.70, Y distorts to -9 and +21. The only solution is increase the Newmans, trading sexy distortion for a flat Y curve.
In the spirit of peer review, I’ve posted the project one my Subversion server for anyone to use, mess around with, or make fun of. All I ask in return is that you mock me in such a way I can learn from it.
Addenda
Few comments on this entry, but it was a not for naught. Elliot got his math on and came up with a great mathematic explanation of the Newman effect.
Frank
Another way to look at it is that while the map is flipping around the Y axis, the axis of rotation moves backward into the viewport and then out again, its position tracing out the first bump of a sine wave during the flip.
That said, I have no idea what that means in term of whatever opaque struct you have to set up to get Core Animation to do it.
Andre
I'll definitely use this in an iPhone, and maybe even an OS X app. Good tip!
Dan
Thanks for sharing Mike. As I'm still a newbie on coding in Cocoa and such I appreciate being able to see examples like this so I can learn.
Arden
Your example doesn't work on the new version of iPhone's map app, as it now flips the map back as if it were a page. Is there another place where we can see this in action on iPhone?
Arden
Hmm, I found 2 places, actually. The weather and stock apps both do this flipping when you tap the little info buttons. I'll still have to see how this compares on the computer when I get home, though.