使用CATransform3DMakeRotation时无法产生透视效果

3

我正在尝试使用CATransform3DMakeRotation对UIView层进行3D旋转。但是,我很困惑为什么这个简单的示例没有显示透视效果,而是看起来被挤压了。当我使用CATransform3DRotate时,可以让旋转生效,但我不想旋转一定角度,我想要旋转到某个位置。谢谢。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    UIView *newView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    [newView setBackgroundColor:[UIColor orangeColor]];
    UILabel *newLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 50, 20)];
    [newLabel setText:@"Hello"];
    [newView addSubview:newLabel];
    [self.window addSubview:newView];

    CALayer *layer = newView.layer;

    CATransform3D perspective = CATransform3DMakeRotation(1.0, 0, 1, 0);
    perspective.m34 = -1 / 500;

    layer.anchorPoint = CGPointMake(1.0, 0.5);
    layer.zPosition = 99;
    layer.transform = perspective;

    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

这是一个关于IT技术的翻译内容,以下是需要翻译的文本:

这是它的截图:

截图

在David的回答之后更新:

为了加强David的观点,即顺序很重要,我想看到矩阵中的差异并编写了以下代码:

CATransform3D transform1 = CATransform3DMakeRotation(-1, 0, 1, 0);
transform1.m34 = -1.0 / 500.0;

NSLog(@"%f %f %f %f", transform1.m11, transform1.m12, transform1.m13, transform1.m14);
NSLog(@"%f %f %f %f", transform1.m21, transform1.m22, transform1.m23, transform1.m24);
NSLog(@"%f %f %f %f", transform1.m31, transform1.m32, transform1.m33, transform1.m34);
NSLog(@"%f %f %f %f", transform1.m41, transform1.m42, transform1.m43, transform1.m44);

NSLog(@"==============================");

CATransform3D transform2 = CATransform3DIdentity;
transform2.m34 = -1.0 / 500.0;
transform2 = CATransform3DRotate(transform2, -1, 0, 1, 0);

NSLog(@"%f %f %f %f", transform2.m11, transform2.m12, transform2.m13, transform2.m14);
NSLog(@"%f %f %f %f", transform2.m21, transform2.m22, transform2.m23, transform2.m24);
NSLog(@"%f %f %f %f", transform2.m31, transform2.m32, transform2.m33, transform2.m34);
NSLog(@"%f %f %f %f", transform2.m41, transform2.m42, transform2.m43, transform2.m44);

NSLog(@"==============================");

CATransform3D transform3 = CATransform3DIdentity;
transform3 = CATransform3DRotate(transform3, -1, 0, 1, 0);
transform3.m34 = -1.0 / 500.0;

NSLog(@"%f %f %f %f", transform3.m11, transform3.m12, transform3.m13, transform3.m14);
NSLog(@"%f %f %f %f", transform3.m21, transform3.m22, transform3.m23, transform3.m24);
NSLog(@"%f %f %f %f", transform3.m31, transform3.m32, transform3.m33, transform3.m34);
NSLog(@"%f %f %f %f", transform3.m41, transform3.m42, transform3.m43, transform3.m44);

这将产生以下输出:

0.540302 0.000000 0.841471 0.000000
0.000000 1.000000 0.000000 0.000000
-0.841471 0.000000 0.540302 -0.002000
0.000000 0.000000 0.000000 1.000000
==============================
0.540302 0.000000 0.841471 -0.001683
0.000000 1.000000 0.000000 0.000000
-0.841471 0.000000 0.540302 -0.001081
0.000000 0.000000 0.000000 1.000000
==============================
0.540302 0.000000 0.841471 0.000000
0.000000 1.000000 0.000000 0.000000
-0.841471 0.000000 0.540302 -0.002000
0.000000 0.000000 0.000000 1.000000

你设置 .m34 为 -1 / 500,这可能是整数除法吗?试着使用 -1.0 / 500.0 - Zev Eisenberg
@ZevEisenberg 感谢您的建议,但它没有起作用。 - uff da
2个回答

18

设置m34值并不能通过魔法使所有变换都具有透视效果(不幸的是)。由于旋转会改变变换的许多不同值,您需要在恒等矩阵上设置透视,然后旋转该变换。

CATransform3D rotationWithPerspective = CATransform3DIdentity;
rotationWithPerspective.m34 = -1.0/500.0;
rotationWithPerspective = CATransform3DRotate(rotationWithPerspective, angle, 0, 1, 0);

你现在做的与这里的不同之处在于,你创建了一个单位矩阵并将透视设置在上面,然后旋转该矩阵。问题在于顺序很重要。


如果你懂矩阵数学,那么你可以验证这两种变换之间的差异,并了解为什么你的变换没有给你任何透视效果。如果你有兴趣学习变换背后的数学知识,我写了一篇关于它的博客文章(警告:它相当冗长,并且只包含数学)。


@david哦,要是我早知道顺序很重要的话)非常感谢! - Mykola Denysyuk

0

我一直觉得m34属性很棘手,试试这个:

CATransform3D transform = CATransform3DIdentity;

而不是 CATransform3DMakeRotation(1.0, 0, 1, 0);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接