Нет перспективы при использовании CATransform3DMakeRotation
Я пытаюсь выполнить 3D вращение на слое UIView, используя 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;
}
Вот скриншот того, как это выглядит:
ОБНОВЛЕНИЕ после ответа Дэвида:
Просто чтобы подчеркнуть точку зрения Дэвида, что порядок имеет значение, я хотел увидеть разницу в матрицах и закодировал это:
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
2 ответа
Настройка m34
значение не дает вам перспективы для всех преобразований с помощью магии (к сожалению). Так как вращение изменяет множество различных значений преобразования, вам нужно установить перспективу для сообщения идентификации и затем повернуть это преобразование.
CATransform3D rotationWithPerspective = CATransform3DIdentity;
rotationWithPerspective.m34 = -1.0/500.0;
rotationWithPerspective = CATransform3DRotate(rotationWithPerspective, angle, 0, 1, 0);
Отличие от того, что вы делаете, состоит в том, что вы создаете матрицу идентичности и задаете перспективу, а затем вращаете эту матрицу. Проблема в том, что порядок имеет значение.
Если вы знаете матричную математику, вы можете проверить разницу между этими двумя преобразованиями и понять, почему ваши не дают вам никакой перспективы. Если вы заинтересованы в изучении математики преобразований, я написал об этом пост в блоге (предупреждение: оно довольно длинное и содержит только математику).
Я всегда считал свойство m34 привередливым, попробуйте это:
CATransform3D transform = CATransform3DIdentity;
вместо CATransform3DMakeRotation(1.0, 0, 1, 0);