Question

I have rotated a view 50 degrees around the y axis using Core Animation. I want the edge of the view to be touching the edge of the screen. How can I do this?

I know the length of the view and the amount of degrees by which the view was rotated (50 degrees), so at first thought, I figured I could determine the distance between the view and the edge using trigonometry. However, the camera's perspective is affected by the m34 property of the CATransform3D struct. How can I figure out the distance I need to move the view to align with the edge of the screen?

CATransform3D rotation = CATransform3DIdentity;
rotation.m34  = -1.0/500.0;
rotation = CATransform3DRotate(rotation, 50.0 * M_PI / 180, 0.0, 1.0, 0.0);
view.layer.transform = rotation;
view.layer.zPosition = 200;

enter image description here

Was it helpful?

Solution

If I understood you correctly, you want something like the following:

Final view

To ease your calculations you need to play with the anchorPoint of the CALayer. The anchorPoint is where the transformations are applied, and its effects are specially visible in rotations. What we are going to do is tell the CALayer to rotate around one of its points, not the center (which is the default).

This is my loadView:

UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
view.backgroundColor = [UIColor whiteColor];

CGRect frame = CGRectMake(view.frame.size.width - 100.f,
                          view.frame.size.height / 2.f - 50.f,
                          100.f, 100.f);
UIView *red = [[UIView alloc] initWithFrame:frame];
red.backgroundColor = [UIColor redColor];
[view addSubview:red];

CATransform3D rotation = CATransform3DIdentity;
rotation.m34  = -1.0/500.0;
// Since the anchorPoint is displaced from the center, the position will move with
// it, so we have to counteract it by translating the layer half its width.
rotation = CATransform3DTranslate(rotation, 50.f, 0, 0);
rotation = CATransform3DRotate(rotation, 50.0 * M_PI / 180, 0.0, 1.0, 0.0);
// We tell the anchorPoint to be on the right side of the layer (the anchor point
// position is specified between 0.0-1.0 for both axis).
red.layer.anchorPoint = CGPointMake(1.f, 0.5f);
red.layer.transform = rotation;
red.layer.zPosition = 200;

And what I obtain is the image you see above.

Hope it helps!

OTHER TIPS

You want to apply your final transformation matrix (including the M34 change) to the end points of the edge of your view who's distance you're trying to calculate. That will give you the final location of your point in projected space.

iOS 5 added GLKit, which includes a whole library of functions for doing matrix and vector calculations. Take a look at GLKMatrix4MultiplyVector3, for example. That function takes a 3 part vector and multiplies it by a 4x4 matrix, and returns a resulting 3-component vector.

You might need GLKMatrix4MultiplyVector4, since if I remember correctly you want your vector to have 1 more component than the number of axes (so for a 3D vector you want a 4 component vector.) Vector math isn't my strong suit, so I have to look this stuff up when I need to use it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top