2012-01-04 4 views
3

정말 도움이 될 것입니다. 뷰에 3D 변환을 적용 했으므로 렌더링 된 뷰의 가장자리 좌표를 식별하여 인접한 다른 뷰를 픽셀 간격없이 표시 할 수 있어야합니다. 특히 나는 각도를 움직여서 전단지처럼 접을 수있는 일련의 뷰 ("페이지")를 원합니다.iOS CATransform3D 좌표

int dir = (isOddNumberedPage ? 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 

는 내가있는 CALayer, 내가 찾은 일부 매트릭스 수학의 코드 조각을 사용하여에 실패한 시도를 검사하여이 일을 여러 가지 방법을 시도하지만, (가까이에 따라 심지어 균열 또는 수 없어 각도, 좋은 20 픽셀). 매트릭스 수학 교과서를 읽는 데 2 ​​주를 소비하지 않고도이 작업을 수행 할 수있는 방법이 있습니까?

답변

5

뷰의 프레임은 수퍼 뷰의 좌표계에서 축으로 정렬 된 사각형입니다. 프레임은 뷰의 범위를 완전히 둘러 쌉니다. 뷰가 변형되면 프레임이 뷰의 새 경계를 단단히 둘러싸 기 위해 조정됩니다.

Y 축 회전 및 원근감을 뷰에 적용하면 뷰의 왼쪽 및 오른쪽 가장자리가 앵커 포인트 (일반적으로 뷰의 중심)쪽으로 이동합니다. 왼쪽 가장자리도 키가 커지거나 짧아지고 오른쪽 가장자리는 반대가됩니다.

그래서 (변환을 적용한 후) 뷰의 프레임은 변환 된 뷰의 왼쪽 가장자리 좌표와 너비와 더 높은 가장자리의 위쪽과 높이를 제공합니다 (왼쪽 또는 오른쪽 가장자리 중 하나 일 수 있음).). 여기 내 테스트 코드는 다음과 같습니다

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)); 

다음은 출력입니다 :

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}} 

는 또한 convertPoint:fromView: 또는 convertPoint:toView:를 사용하여 슈퍼 뷰의 좌표 공간에서, 뷰의 모서리의 좌표를 얻을 수 있습니다. 테스트 코드 :

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); 

출력 : Y가 upperLeft 및 upperRight 점의 좌표 것을

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} 

주의가 슈퍼 뷰의 좌표계에서 다르다.

+0

감사합니다. Rob - 당신은 절대적인 스타입니다. 몇 가지 시도가 내 시나리오에서 작동하도록 만들었지 만, 당신의 설명이 거기에있어 그래서 거기에있어. – Phil

관련 문제