11
01.11
ADDING 3RD DIMENSION TO THE PAGE FLIP EFFECT ON IPHONE OS
Comments: 12 comments
Category: Tips for Developers
3d page flip animation created using cocos2d framework.
My 3d concept of flipping a page is based on its 2d version. We will still reflect points that are in front of the symmetry axis but we will also modify the z coordinate of these points (see picture 5).
Pic.5. 3d version of page flip effect.
To understand the concept, imagine a cylinder with a large radius which is running on the same path as the symmetry axis. When the cylinder touches the paper, it begins to wrap around the cylinder until it reaches the cylinder’s top edge. After that, the piece of paper which has passed the cylinder’s top edge (actually the grid’s vertices that represent that piece of paper) should behave as if they were reflected across the symmetry axis. So the z value of the moveable points should be between 0 and 2*R (R is a radius of the cylinder).
Pic. 6. Cross section of the page wrapped around the cylinder.
The radius of the cylinder decreases in time.
The radius of the cylinder decreases in time.
To make the whole effect even more realistic the radius of the cylinder should decrease from its maximum value to zero in time. Below is a piece of code which does all mentioned stuff. In the code I use Vertex and Point data structures. I did an assumption that Vertex and Point represent points in 3d and 2d space respectively. But it’s fair to treat points as vertices with z = 0. So if you see p = 5 * v; it means that only x and y coordinates take part in calculation.
// time is a value from 0 to 1; // 0  begin of the effect, // 1  whole page has been flipped void update(float time) { const Point A, B', C, D; // corners of the animated page (except B') const float t = sqrt(time); const Point P1 = lerp(B', A, t); const Point P2 = lerp(C, D, t); const Line line = CreateLineFromPoints(P1, P2); const Point N = GetNormalVectorFromLine(line); const float maxRadius = 0.5 * pageWidth * pi; float R; if (time <= 0.5) { // for the first half of the effect keep a fixed value of radius R = maxRadius; } else { // in the second half decrease the radius from its max value to 0 const float s = sqrt( 2 * (1  time) ); // note that "2 * (1  time)" is between 0 and 1, so is "s" R = (0, maxRadius, s); // <=> R = maxRadius * s; } const float invR = 1 / R; const float halfCylinderCircumference = π * R; // π ≈ 3.14159 Vertex v; for v in grid.vertices { const float dist = distance(v, line); if (dist > 0) { const Point p = v  N * dist; if (dist <= halfCylinderCircumference) { const float alpha = dist * invR; const float sinAlpha = R * sin(alpha); v.x = p.x + N.x * sinAlpha; v.y = p.y + N.y * sinAlpha; v.z = (1  cos(alpha)) * R; } else { v.x = p.x  N.x * (dist  halfCylinderCircumference); v.y = p.y  N.y * (dist  halfCylinderCircumference); v.z = 2 * R; } } } }
Summary
This is the easiest 3d version of page flip algorithm I can imagine. It’s not perfect. It’s still have artefacts when viewing in slow motion but when animation is fast enough it looks realistic. The best approach to the page curl simulation is to use cone instead of cylinder (see W. Dana Nuon blog for details). But no matter what solid you use, the idea is the same, only equations may vary.

Nicolas Lau

Prosenjit


felix

http://technoface.com.tr saltik

Ali

Bala

sb ceress

thirupathi

steve

http://www.dotto.com.tr Dotto

Jose

Prosenjit