A page turning UI effect made with unity, the paper deformation is determined by the pins’ position on it.
This algorithm is about wrapping a paper around a cylinder and calculate the vertexes’ positions on the paper. First, let’s imagine dragging the mouse from a paper’s right up corner, and a cylinder whose central axis always pass through the mouse position and perpendicular to the mouse drag direction dynamically, just like Fig.1.
Cylinder central axis
The mouse drag direction will be determined by the current mouse position and a corner of the parper, that means as you clicked and dragging the mouse on the paper, the start point of the vector will always be one of the four corners of the paper and end point is the mouse’s position. You may ask why not calculated the vector by the mouse’s position in last frame as the start point and the mouse’s position in this frame as the end point. Try it and look the paper’s behaviour 😃
Assume we drag the paper at right up corner on 3D coordinate system, the paper is on the xz coordinate plane and its corner position is
(x0, y0, z0). Currently the mouse’s position is
(x1, y1, z1). The straight line equation can be derived as
z=(z1-z0)/(x1-x0)*x+z1+(z0-z1)/(x1-x0)*x1. Then the central axis of the cylinder which is perpendicular to the mouse dragging direction can be derived as
The right up part of the paper will be wrapped on the cylinder as Fig.2.
Let’s choose a vertex on the paper, its position is
(xv, yv, zv), the distance of the vertex to the cylinder’s central axis on xz coordinate plane is
In Fig.2, we can get
θ=dist/R (clyinder’s radius is
R). The y position of the vertex on the paper after wrapping on the cylinder is
The move direction on xz coordinate plane of this vertex is
dir=(x1, z1)-(x0, z0). The xz position of the vertex on the paper after wrapping on the cylinder is
When the paper wrapped on the cylinder exceed 180 degree, we flatten the exceed part and the position of vertexes on this part can be derived as
(xv, zv)+normalized(dir)*(dist+dist-pi*R) and
yv=2*R, if you can not figure out the equation, just try to draw the image as Fig.2 and wrap large part of the paper on the cylinder.
We need to determine which part of the paper should be wrapped on the cylinder, we can use cross product to check if the vertex on the paper is in clockwise direction of the vector which is acquired by rotating the mouse dragging direction 90 degree in clockwise direction. The start point of the vector is
(x1, z1), the end point of the vector is
(x2, z2), the check point is
(x3, z3). The cross product is
(x1-x3)*(z2-z3)-(x2-x3)*(z1-z3), if it’s negative the check point is in clockwise direction.
When the mouse button up, the paper need to be flattened smoothly. This can be implemented by scrolling the cylinder back along the mouse drag direction to the paper’s corner.
Paper deformation with considering Pins on it
Let’s imagine turning a paper which has a pin on it. The paper curling as you dragging it from right to left until it touches a pin. Unless you tear the paper, it can not move along current drag direction anymore. We can only drag the paper around the pin, but not curling it. This effect is really easy to implement 😃
Assume we put lots of pins on a paper, then we drag the paper from right up corner to left as some direction. How could we determine which pin is first touched by the cylinder’s central axis? We have derived the direction which is acquired by rotating the mouse drag direction 90 degree in clockwise direction
newDir=(z1-z0, x0-x1). We only need to set the start point of the vector as a pin’s position, and check if there is a pin in clockwise direction of it (just like what we did in above to check which part of the paper should be wrapped on the cylinder). We find a pin which has no pins in clockwise direction of it, and it must be the first pin the cylinder’s central axis touches.
Now, we have the pin’s position and just replace the mouse position in above calculation as the pin’s position. The steps are:
1. Drag the mouse and acquire the cylinder's central axis; 2. Find the pin which will be first touched by the cylinder's central axis; 3. Scroll back the cylinder from mouse's position to pin's position with keeping its direction unchanged.
That’s the main part of this page turning algorithm, if you have any question, please don’t hesitate to contact me 😃