example code can be downloaded in http://download.csdn.net/detail/worldmatrix/4603488
iOS UI is based on the UIView class, and every UI element we can see is a subclass of UIView or UIView. The view is organized in a tree-shaped structure and the roots are UIWindow.
view is responsible for the interaction and display of the interface, where the display is partially done by Calayer. Each uiview contains an instance of Calayer. It can be thought that the uiview itself is not visible, and all we can see is that Calayer,uiview is only responsible for managing the Calayer.
UIView display settings are encapsulated for the Calayer attribute, but this layer of encapsulation masks the 3D display functionality provided by Calayer. So we want to let UIView show the effect of the results, we need to operate the Calayer directly.
to manipulate Calayer objects, first include quartzcore.framework in the project, import <QuartzCore/QuartzCore.h> header files in the file. The quartzcore.framework contains definitions of calayer and some of the official subclasses of Calayer.
by setting the Transform property of the Calayer, you can make calayer shift, zoom, rotate, and so on in 3D space.
The first example is the rotation around the axis:
Original Scene
Use Image.layer.transform = catransform3dmakerotation (M_PI/6, 0, 0, 1), and the effect of rotating 30 degrees around the z-axis
Use Image.layer.transform = catransform3dmakerotation (M_PI/6, 0, 1, 0), and rotate 30 degrees around the y-axis effect
Use Image.layer.transform = Catransform3dmakerotation (M_PI/6, 1, 0, 0), and rotate 30 degrees around the x-axis effect
It is possible to find that the rotation around the z-axis is expected, but the rotation around the y-axis of the x-axis is just some scaling on the x-axis of the y-axis. This is because, in the Calayer display system, the default camera uses orthogonal projections, and the orthographic projection is not much smaller, so in this case, it can only cause scaling on the corresponding axis.
A second example, perspective projection
Calayer uses orthogonal projections by default, so there is no near-large effect, and there is no explicit API to use the perspective projection matrix. Fortunately, you can construct a perspective projection matrix from a matrix connection. The code for constructing a perspective projection matrix is as follows:
catransform3d catransform3dmakeperspective (cgpoint Center, float Disz)
{
Catransform3d transtocenter = catransform3dmaketranslation (-center.x,-center.y, 0);
Catransform3d transback = catransform3dmaketranslation (center.x, center.y, 0);
Catransform3d scale = catransform3didentity;
scale.m34 = -1.0f/disz;
return Catransform3dconcat (Catransform3dconcat (transtocenter, scale), transback);
}
catransform3d catransform3dperspect (Catransform3d T, Cgpoint Center, float Disz)
{
return Catransform3dconcat (T, catransform3dmakeperspective (center, Disz));
}
The principle of this function should refer to the 3D transform part of computer graphics, and then explain it later. Now just need to understand the meaning of the interface, center refers to the location of the camera, the camera position is relative to the calayer to be transformed, the origin is Calayer anchorpoint in the entire calayer position, for example, the size of Calayer is (100, ), the Anchorpoint value is (0.5, 0.5), at this time anchorpoint in the entire Calayer position is (50, 100), the position of the center. The camera position of the incoming Perspective transformation is (0, 0), then the camera is located in the position relative to Calayer (50, 100). If you want the camera to be in the upper-left corner, you need to pass in (-50,-100). Disz represents the distance the camera is from the z=0 plane (which can also be interpreted as a screen).
the rotation with perspective effect is as follows:
Catransform3d rotate = catransform3dmakerotation (M_PI/6, 1, 0, 0);
image.layer.transform = catransform3dperspect (rotate, cgpointmake (0, 0), (+);
Catransform3d rotate = catransform3dmakerotation (M_PI/6, 0, 1, 0);
image.layer.transform = catransform3dperspect (rotate, cgpointmake (0, 0), (+);
Catransform3d rotate = catransform3dmakerotation (M_PI/6, 0, 0, 1);
image.layer.transform = catransform3dperspect (rotate, cgpointmake (0, 0), (+);
The default anchorpoint of image is (0.5,0.5), that is, in the center of the picture; The eye is in the center of the picture, 200 units away from the screen. Can be observed, because the flip, so that the different parts of the picture from the screen distance, nearly large and small effect so that the three-dimensional greatly improved. The rotation of the z-axis does not change because of the perspective, because all points are the same distance from the screen, so it does not produce a much smaller perspective.
third, more effects. Calayer rotation and scaling is around anchorpoint points, changing the value of Anchorpoint, you can make the layer around different points and not just the center point rotation scaling. As you can see in the example of constructing a perspective projection matrix, Catransform3d can be connected using the Catransform3dconcat function to construct more complex transformations. With these methods, more effects can be combined. The following is a flipped animation. Using Uitimer
-(void) Update
{
static float angle = 0;
angle + = 0.05f;
Catransform3d transloate = catransform3dmaketranslation (0, 0, -200);
Catransform3d rotate = catransform3dmakerotation (angle, 0, 1, 0);
Catransform3d mat = catransform3dconcat (rotate, transloate);
image.layer.transform = Catransform3dperspect (Mat, cgpointmake (0, 0), +);
}
Finally, there are two more complex examples. The first one is to use four pictures of the same size to enclose a box to animate the box.
Catransform3d move = catransform3dmaketranslation (0, 0,);
Catransform3d back = catransform3dmaketranslation (0, 0, -160);
Catransform3d rotate0 = catransform3dmakerotation (-angle, 0, 1, 0);
Catransform3d rotate1 = catransform3dmakerotation (m_pi_2-angle, 0, 1, 0);
Catransform3d rotate2 = catransform3dmakerotation (m_pi_2*2-angle, 0, 1, 0);
Catransform3d rotate3 = catransform3dmakerotation (m_pi_2*3-angle, 0, 1, 0);
Catransform3d mat0 = Catransform3dconcat (Catransform3dconcat (move, Rotate0), back);
Catransform3d mat1 = Catransform3dconcat (Catransform3dconcat (move, rotate1), back);
Catransform3d mat2 = Catransform3dconcat (Catransform3dconcat (move, Rotate2), back);
Catransform3d MAT3 = Catransform3dconcat (Catransform3dconcat (move, Rotate3), back);
image0.layer.transform = Catransform3dperspect (Mat0, Cgpointzero, n);
image1.layer.transform = Catransform3dperspect (MAT1, Cgpointzero, n);
image2.layer.transform = Catransform3dperspect (MAT2, Cgpointzero, n);
image3.layer.transform = Catransform3dperspect (MAT3, Cgpointzero, n);
The above example uses UIImage's Calayer, but the Calayer generated animation can be applied to all uiview and subclasses, the following is a general interface of the three-dimensional flip effect.
float dis = 1.732f;
Catransform3d move = catransform3dmaketranslation (0, 0, dis);
Catransform3d back = catransform3dmaketranslation (0, 0,-dis);
Catransform3d rotate0 = catransform3dmakerotation (-angle, 0, 1, 0);
Catransform3d rotate1 = catransform3dmakerotation (-angle + m_pi/3.0f, 0, 1, 0);
Catransform3d mat0 = Catransform3dconcat (Catransform3dconcat (move, Rotate0), back);
Catransform3d mat1 = Catransform3dconcat (Catransform3dconcat (move, rotate1), back);
view0.layer.transform = Catransform3dperspect (Mat0, Cgpointzero, n);