使用 CATransform3D 实现梯形变换

Achieve a trapezoid transform with CATransform3D

我想更改 UIView 来自:

         o---o
         |   |
         |   |
         |   |
         |   |
         |   |
         o---o

收件人:

            /o
           / |
         o/  |
         |   |
         o\  |
           \ |
            \o

请原谅我的 ascii 艺术。我的意思是将矩形背景更改为梯形背景,其中:

我试过这个:

CATransform3D sublayerTransform = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, .005, 0, 0, 0, 1 };
self.backgroundView.layer.superlayer.sublayerTransform = sublayerTransform;
CATransform3D layerTransform = CATransform3DMakeRotation(M_PI/4., 0, 1, 0);
self.backgroundView.layer.transform = layerTransform;

结果是一个梯形,但它没有所需的约束。

看看 CATrasnsform3D 矩阵,在你的情况下,你真的只需要设置 .m34。

请记住,CATransform3DRotate 将弧度作为其参数之一,定义如下;

  float Degrees2Radians(float degrees) { return degrees * M_PI / 180; }

尝试以下操作;

  CATransform3D transform = CATransform3DIdentity;
  transform.m34 = -1.0f /450.0f; 

  // set y to  negative for effect on left(as in your diagram), positive for effect on right
  transform = CATransform3DRotate(transform, Degrees2Radians(45) , 0.0f, -1.0f, 0.0f);

  // you'll need to do this translate to shift the layer to compensate for  the rotation
  transform = CATransform3DTranslate(transform, -70.0f, 0.0f, -50.0f);

然后显然将目标层变换设置为上面的变换

我能够使用 AGGeometryKit.

轻松实现正确的 CATransform3D
#import <AGGeometryKit/AGGeometryKit.h>

UIView *view = ...; // create a view

// setting anchorPoint to zero
view.layer.anchorPoint = CGPointZero;
view.layer.transform = CATransform3DMakeTranslation(-view.layer.bounds.size.width * .5, -view.layer.bounds.size.height * .5, 0);

// setting a trapezoid transform
AGKQuad quad = view.layer.quadrilateral;
quad.tl.y += 10; // shift top left y-value with 10 pixels
quad.bl.y -= 10; // shift bottom left y-value with 10 pixels
view.layer.quadrilateral = quad; // the quad is converted to CATransform3D and applied