Search code examples
iosuiimageviewrotationcore-animationcalayer

Why does translating the CALayer around x-axis affects the rotation around Y axis


I have a CALayer added and transformed the following way. I would assume that translating the layer by any constant before rotation should not have an effect on rotation around Y axis but it seems to make a difference, what am I missing here ?

- (void)viewDidAppear:(BOOL)animated
{
    CALayer* layer = [CALayer layer];
    layer.bounds = self.img1.bounds;
    layer.backgroundColor = [[UIColor grayColor] CGColor];
    layer.anchorPoint = CGPointMake(0, 0.5);
    layer.position = CGPointMake(0, CGRectGetMidY(self.view.bounds));
    layer.contents = (id)[self.img1.image CGImage];
    layer.transform = [self transformforView1];
    [self.view.layer addSublayer:layer];
}

Rotation without any translation and output:

- (CATransform3D)transformforView1
{
    CATransform3D t = CATransform3DIdentity;
    t.m34 = 1.0/-700;
    t = CATransform3DTranslate(t, 0, 0, 0);
    t = CATransform3DRotate(t, degToRad(45), 0, 1, 0);
    return t;
}

Rotation without any translation and output

Same rotation with translation of 500 and output:

- (CATransform3D)transformforView1
{
    CATransform3D t = CATransform3DIdentity;
    t.m34 = 1.0/-700;
    t = CATransform3DTranslate(t, 500, 0, 0);
    t = CATransform3DRotate(t, degToRad(45), 0, 1, 0);
    return t;
}

Same rotation with translation of 500 and output


Solution

  • This is actually a very good question. The confusion comes from the fact that Model View Matrix and Projection Matrix are usually separate.

    Read this Question for reference:

    The purpose of Model View Projection Matrix

    I'd suggest you separate your Model View Matrix and Projection Matrix.

    So your CATransform3D t is effectively the concatenation of the two matrices, you could add another translation to move your model in the view or then create another transformation (your Model View Matrix). This is what I've done here:

    CATransform3D modelViewTransform = CATransform3DMakeTranslation([UIScreen mainScreen].bounds.size.height / 2.0, 0, 0);
    CATransform3D t = CATransform3DIdentity;
    t.m34 = 1.0/-700;
    t = CATransform3DTranslate(t, 500, 0, 0);
    t = CATransform3DRotate(t, degToRad(45), 0, 1, 0);
    return CATransform3DConcat(t, modelViewTransform);
    

    This will move your model to the center of the screen instead of it being at the edge of the screen.