Coorderadas iOS CATransform3D

Realmente agradecería cualquier ayuda en este caso. He aplicado una transformación 3D en una vista y necesito identificar las coorderadas de borde de la vista renderizada para que pueda presentar otra vista adyacente a ella (sin ningún espacio entre píxeles). Específicamente, quiero que una serie de vistas ("páginas") se pliegue como un folleto, al animar el ángulo.

int dir = (isOddNumbenetworkingPage ? 1 : -1); float angle = 10.0; theView.frame = CGRectMake(pageNumber * 320, 0, 320, 460); CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity; rotationAndPerspectiveTransform.m34 = -1.0 / 2000; // Perspective rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, dir * angle / (180.0 / M_PI), 0.0f, 1.0f, 0.0f); theView.layer.transform = rotationAndPerspectiveTransform; // Now need to get the top, left, width, height of the transformed view to correct the view's left offset 

He intentado varias forms de hacerlo inspeccionando el CALayer, un bash fallido de utilizar algunos fragments de código matemáticos matriciales que encontré, pero no he podido descifrarlo ni siquiera acercarme (según el ángulo, unos 20 píxeles de salida ) ¿Hay alguna manera de que pueda hacer esto sin pasar 2 semanas leyendo un libro de text matemático matricial?

El marco de una vista es un rectángulo alineado con el eje en el sistema de coorderadas de la vista superior. El marco encierra completamente los límites de la vista. Si la vista se transforma, el marco se ajusta para encerrar estrechamente los nuevos límites de la vista.

Cuando aplica una rotation y perspectiva del eje Y a una vista, los bordes izquierdo y derecho de la vista se mueven hacia su punto de anclaje (que normalmente es el centro de la vista). El borde izquierdo también crece más alto o más corto, y el borde derecho hace lo contrario.

Entonces, el marco de la vista (después de aplicar la transformación) le dará la coorderada del borde izquierdo y el ancho de la vista transformada, y la parte superior y la altura del borde más alto (que podría ser el borde izquierdo o derecho). Aquí está mi código de testing:

 NSLog(@"frame before tilting = %@", NSStringFromCGRect(self.tiltView.frame)); float angle = 30.0; CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity; rotationAndPerspectiveTransform.m34 = -1.0 / 2000; // Perspective rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 1 * angle / (180.0 / M_PI), 0.0f, 1.0f, 0.0f); self.tiltView.layer.transform = rotationAndPerspectiveTransform; NSLog(@"frame after tilting = %@", NSStringFromCGRect(self.tiltView.frame)); 

Aquí está el resultado:

 2012-01-04 12:44:08.405 layer[72495:f803] frame before tilting = {{50, 50}, {220, 360}} 2012-01-04 12:44:08.406 layer[72495:f803] frame after tilting = {{62.0434, 44.91}, {190.67, 370.18}} 

También puede get las coorderadas de las esquinas de la vista, en el espacio de coorderadas de la vista de supervisión usando convertPoint:fromView: o convertPoint:toView: Código de testing:

  CGRect bounds = self.tiltView.bounds; CGPoint upperLeft = bounds.origin; CGPoint upperRight = CGPointMake(CGRectGetMaxX(bounds), bounds.origin.y); CGPoint lowerLeft = CGPointMake(bounds.origin.x, CGRectGetMaxY(bounds)); CGPoint lowerRight = CGPointMake(upperRight.x, lowerLeft.y); #define LogPoint(P) NSLog(@"%s = %@ -> %@", #P, \ NSStringFromCGPoint(P), \ NSStringFromCGPoint([self.tiltView.superview convertPoint:P fromView:self.tiltView])) LogPoint(upperLeft); LogPoint(upperRight); LogPoint(lowerLeft); LogPoint(lowerRight); 

Salida:

 2012-01-04 13:03:00.663 layer[72635:f803] upperLeft = {0, 0} -> {62.0434, 44.91} 2012-01-04 13:03:00.663 layer[72635:f803] upperRight = {220, 0} -> {252.713, 54.8175} 2012-01-04 13:03:00.663 layer[72635:f803] lowerLeft = {0, 360} -> {62.0434, 415.09} 2012-01-04 13:03:00.663 layer[72635:f803] lowerRight = {220, 360} -> {252.713, 405.182} 

Observe que las coorderadas Y de los puntos upperLeft y upperRight son diferentes en el sistema de coorderadas de la supervisión.