2012-01-04 12 views
3

これは本当に役に立ちますか?私はビューに3D変換を適用し、レンダリングされたビューのエッジ座標を特定する必要があるため、隣接する別のビューをピクセル間隔なしで表示することができます。具体的には、一連のビュー(「ページ」)を、リーフレットのように折りたたむには、角度をアニメーション化してください。iOS CATransform3D Coordinates

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

出力:左上とupperRight点のY座標はスーパーの座標系が異なること

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

ありがとうございます。あなたは絶対星です。私のシナリオでそれを動作させるためにいくつか行ったが、あなたの説明はそこにあったので、そこに私を得た。 – Phil

関連する問題