3

を使用して UIView レイヤーで 3D 回転を実行しようとしていCATransform3DMakeRotationます。なぜこの単純な例がパースペクティブを示さず、代わりに押しつぶされたように見えるのか、私は混乱しています。を使用すると回転を機能させることができますが、回転さ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;
}

これがどのように見えるかのスクリーンショットです:

スクリーンショット

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
4

2 に答える 2

18

値を設定しても、 m34(残念ながら) 魔法によるすべての変換の見通しが得られるわけではありません。回転は変換のさまざまな値を変更するため、ID メッセージにパースペクティブを設定してから、その変換を回転させる必要があります。

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

ここで行っていることとの違いは、恒等行列を作成し、その上に視点を設定してから、その行列を回転させることです。問題は、順序が重要であることです。


行列の計算を知っている場合は、2 つの変換の違いを確認し、自分の変換が視点を与えない理由を確認できます。変換の背後にある数学について学ぶことに興味があるなら、私はそれについてのブログ投稿を書きました(警告: 非常に長く、数学のみが含まれています)。

于 2013-02-12T21:29:21.090 に答える
0

私はいつも m34 プロパティが厄介であることに気づきました。これを試してください:

CATransform3D transform = CATransform3DIdentity;

それ以外のCATransform3DMakeRotation(1.0, 0, 1, 0);

于 2013-02-12T20:18:35.323 に答える