2010-06-22 51 views
0

我目前正在通過觸摸,拖動和釋放來旋轉UIImageView。我對功能旋轉對象:iPhone旋轉功能和手工製作的數學旋轉不一致

-(void)rotateForTime:(CGFloat)time distance:(CGFloat)distance 
{ 
    CABasicAnimation* rotationAnimation; 
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    rotationAnimation.toValue = [NSNumber numberWithFloat:distance]; 
    rotationAnimation.removedOnCompletion = NO; 
    rotationAnimation.fillMode = kCAFillModeForwards; 
    rotationAnimation.duration = time; 
    rotationAnimation.repeatCount = 1.0; 
    rotationAnimation.timingFunction = [CAMediaTimingFunctionfunctionWithName: 
               kCAMediaTimingFunctionEaseOut]; 
    rotationAnimation.delegate = self; 
    [bottle.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
} 

由於旋轉後,矩形圖像變化的界限,以判斷是否在圖像內或不在用戶觸摸,我把角落的軌道通過將圖像旋轉相同的距離旋轉圖像,然後使用矢量 - >邊緣交叉點檢測方法來檢查用戶是否觸摸了矩形的邊界。我用這個功能來旋轉角:

-(void) rotateImageBounds:(CGFloat) angle 
{ 
    // Translate the center and the corners of the image to the origin and their respective positions. 
    corner1.x = corner1.x - bottle.center.x; 
    corner1.y = corner1.y - bottle.center.y; 
    corner2.x = corner2.x - bottle.center.x; 
    corner2.y = corner2.y - bottle.center.y; 
    corner3.x = corner3.x - bottle.center.x; 
    corner3.y = corner3.y - bottle.center.y; 
    corner4.x = corner4.x - bottle.center.x; 
    corner4.y = corner4.y - bottle.center.y; 

    // Rotates the point around the origin/center. 
    // x = x1cos(angle) - x1sin(angle) 
    // y = x1sin(angle) + y1cos(angle) 
    CGFloat tempX; 
    tempX = (corner1.x*cos(angle)) - (corner1.y*sin(angle)); 
    corner1.y = (corner1.x*sin(angle)) + (corner1.y*cos(angle)); 
    corner1.x = tempX; 
    tempX = (corner2.x*cos(angle)) - (corner2.y*sin(angle)); 
    corner2.y = (corner2.x*sin(angle)) + (corner2.y*cos(angle)); 
    corner2.x = tempX; 
    tempX = (corner3.x*cos(angle)) - (corner3.y*sin(angle)); 
    corner3.y = (corner3.x*sin(angle)) + (corner3.y*cos(angle)); 
    corner3.x = tempX; 
    tempX = (corner4.x*cos(angle)) - (corner4.y*sin(angle)); 
    corner4.y = (corner4.x*sin(angle)) + (corner4.y*cos(angle)); 
    corner4.x = tempX; 

    // Translates the points back to the original center of the image. 
    corner1.x = corner1.x + bottle.center.x; 
    corner1.y = corner1.y + bottle.center.y; 
    corner2.x = corner2.x + bottle.center.x; 
    corner2.y = corner2.y + bottle.center.y; 
    corner3.x = corner3.x + bottle.center.x; 
    corner3.y = corner3.y + bottle.center.y; 
    corner4.x = corner4.x + bottle.center.x; 
    corner4.y = corner4.y + bottle.center.y; 
} 

這第一次旋轉後工作正常,邊角看起來像仍然在圖像的角落。但是,更多的旋轉後,圖像和角落不再排隊。據我所知,旋轉方法是準確的,角的數學是正確的。我一直試圖找出這個問題好幾天了。任何幫助將不勝感激。

編輯*問題解決: 我最終讓動畫在完成時自行移除,並在完成後將圖像旋轉到正確的位置(這樣更容易,因爲我也需要在旋轉期間旋轉圖像鼠標運動)。 對於旋轉函數:(角度是鼠標(或觸摸)當前所處的角度,使用atan2(dy,dx)獲得,其中dy是觸摸和中心之間的高度,dx是寬度。這需要旋轉

-(void)rotateForTime:(CGFloat)time distance:(CGFloat)distance 
{ 

animating = TRUE; 
CABasicAnimation* rotationAnimation; 
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
rotationAnimation.fromValue = [NSNumber numberWithFloat:angle]; 
rotationAnimation.toValue = [NSNumber numberWithFloat:distance + angle]; 
rotationAnimation.removedOnCompletion = YES; 
rotationAnimation.fillMode = kCAFillModeForwards; 
rotationAnimation.duration = time; 
rotationAnimation.repeatCount = 1.0; 
rotationAnimation.timingFunction = [CAMediaTimingFunction 
             functionWithName:kCAMediaTimingFunctionEaseOut]; 
rotationAnimation.delegate = self; 

[bottle.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
} 

,然後在動畫結束:

-(void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag 
{ 

animating = FALSE; 
    // Rotates the image to the last spot that the animation rotated to. 
[bottle.layer setValue:[NSNumber numberWithFloat:angle + distance] 
            forKeyPath:@"transform.rotation.z"]; 

    // Gives the corners of the image after rotation (Thanks to mustISignUp) check to make sure 
    // that the touch is within these bounds (I use a ray line intersection algorithm in another part of my code) 
ptInLayerCoords1 = [[bottle.layer presentationLayer] convertPoint:corner1 toLayer:self.view.layer]; 
ptInLayerCoords2 = [[bottle.layer presentationLayer] convertPoint:corner2 toLayer:self.view.layer]; 
ptInLayerCoords3 = [[bottle.layer presentationLayer] convertPoint:corner3 toLayer:self.view.layer]; 
ptInLayerCoords4 = [[bottle.layer presentationLayer] convertPoint:corner4 toLayer:self.view.layer]; 
} 

回答

0

我不熟悉的IPhone,但是這通常發生是由於積累的舍入誤差(這是尤其是如果corner.x/corner.y是整數,則顯而易見)。

要解決,而不是你再次旋轉每一幀(每用戶觸摸屏幕時或,或其他)旋轉的矩形,你只存儲角度偏移從矩形的原始方向,並重新計算新的座標每幀。

+0

非常感謝你,事情就得到了與該計劃,所以我用你的想法添加劑輪換太亂,並儲存在我自己的角度和補充它幫助我解決了這個問題。 – Scotty 2010-06-23 19:33:20

0

正如BlueRaja所說,數學不準確 - 它本質上是近似的,而且你正在積累錯誤。您需要每次重新計算圖層絕對尺寸和旋轉角度的位置,而不是嘗試跟蹤它。

幸運的CALayer能爲你做到這一點沒有太多的麻煩

ptInLayerCoords = [bottle.layer convertPoint:pt fromLayer:self.layer]; 
didHit = [layer containsPoint:ptInLayerCoords]; 
+0

這正是我正在尋找的。我只用了數學,因爲我找不到辦法做到這一點。謝謝。 – Scotty 2010-06-23 19:34:22