Blog
ADDING 3RD DIMENSION TO THE PAGE FLIP EFFECT ON IPHONE OS
Author: Paweł
Comments: 10 comments
You need to install or upgrade Flash Player to view this content, install or upgrade by clicking here.
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.

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.
Paweł
Over 6 years of experience in the design and development of desktop applications, tools, graphics and user interfaces. Worked as a software developer for global companies such as Imagination Technologies and Codemasters.
Comments: 10
10 APR 2011
Nicolas Lau says:
can u give me the source code including sample?

thanks
16 APR 2011
felix says:
Hi, I want source code too.
Please open it :)
19 APR 2011
saltik says:
Hi;
Can u give me the source code including sample?
20 APR 2011
Ali says:
Hi,
Can you please share the source code?
27 APR 2011
Bala says:
Is this possible in BlackBerry Applications?...i need guidance regarding this
26 MAY 2011
sb ceress says:
Can you share your 3D page flip effect source code ?
Thanks in advanced
10 JUN 2011
thirupathi says:
Hi,Can u tel me how to create epub iphone/ipad app.....and kindle book reader app .......please provide code project....

thanks in advance.......
11 JUN 2011
steve says:
Hi.

Can you share your source code?

Thanks .
21 AUG 2011
Dotto says:
Hi there, it's very good job !

Can you share the source code with me?

thanks..
19 SEP 2011
Jose says:
Hi!
Thats just awesome, great look !
Is there a way you can share the source code and the example showed in the video? i would be really thankful .

Thanks!
YOUR NAME*
YOUR WEBSITE
SUBMIT
LEAVE A COMMENT*
This is a moderated site and comments
will appear if and when they are approved.
* required