2012-01-07 34 views
4

我做我的觀點的過渡,總是會發生一些奇怪的,我的意思是我用這個代碼計算角度:angle = atan2f(currentTouchPoint.y - center.y, currentTouchPoint.x - center.x) - atan2f(previousTouchPoint.y - center.y, previousTouchPoint.x - center.x);CGAffineTranformRotate ATAN2 inaccuration

和視圖旋轉,但不正常。我的意思是它在正確的方向旋轉,但角度總是不準確的+/- 0.05弧度。當我再次敲擊時,視圖旋轉到適當的位置。任何adivices?逗號后角度精確到5個位置對我來說很重要。

Some NSLog to show you the problem: 

First rotation first tap and second tap 
2012-01-07 01:01:26.283 Wheel[9080:707] Angle: 0.598412 
2012-01-07 01:01:29.281 Wheel[9080:707] Angle: -0.070008 
Second rotation first tap and second tap 
2012-01-07 01:01:31.103 Wheel[9080:707] Angle: -0.679809 
2012-01-07 01:01:32.450 Wheel[9080:707] Angle: 0.092595 
Third rotation first tap and second tap 
2012-01-07 01:01:35.745 Wheel[9080:707] Angle: 0.607844 
2012-01-07 01:01:36.945 Wheel[9080:707] Angle: -0.064927 
Fourth rotation first tap and second tap 
2012-01-07 01:01:41.073 Wheel[9080:707] Angle: -0.635756 
2012-01-07 01:01:41.920 Wheel[9080:707] Angle: 0.052361 

而我忘了告訴你,條件,點之間的差距越遠,不準確度越大。

編輯:

Circle *view = (Circle *) [self view]; 



for (CircleThumb *thumb in view.subviews) { 


    CGPoint point = [thumb convertPoint:thumb.centerPoint toView:nil]; 
    CircleThumb *shadow = [[view.overlayView subviews] lastObject]; 
    CGPoint centralPoint = [shadow convertPoint:shadow.centerPoint toView:nil]; 
    CGRect shadowRect = [shadow.superview convertRect:shadow.frame toView:nil]; 

    if (CGRectContainsPoint(shadowRect, point) == YES) { 
     CGPoint pointInShadowRect = [thumb convertPoint:thumb.centerPoint toView:shadow]; 
     if (CGPathContainsPoint(shadow.arc.CGPath, NULL, pointInShadowRect, NULL)) { 


      CGAffineTransform current = view.transform; 
      CGPoint center = view.window.center; 
      CGPoint currentTouchPoint =centralPoint; 
      CGPoint previousTouchPoint = point; 

      long double angle = atan2f(currentTouchPoint.y - center.y, currentTouchPoint.x - center.x) - atan2f(previousTouchPoint.y - center.y, previousTouchPoint.x - center.x); 

      [UIView animateWithDuration:0.3f animations:^{ 
       [view setTransform:CGAffineTransformRotate(current, angle)]; 
      }]; 
      [view.delegate circle:view didMoveToSegment:thumb.tag thumb:thumb]; 


      NSLog(@"Angle: %Lf ", angle); 
      break; 
     } 
    }    
} 

這是代碼是一部分 ' - touchesEnded:withEvent:方法' 實施

我正在做一個類似的轉換機器人控制。從我的應用程序和convertbot的「輪子」看起來相似,但我的使用自定義繪圖。

所以Circle是我們旋轉的UIView。 Circle獲得了子視圖 - CircleThumbs。拇指代表圈的單個部分。積分計算得當,但我不會解釋爲什麼,因爲沒有必要。

+0

您能否寄出打印上述信息的代碼?什麼是第一次和第二次水龍頭? – alekhine 2012-01-07 05:16:13

回答

7

atan的計算從來都不是完全正確的。你讓iOS再次計算cos和sin的角度(cgaffinetransformRotate是這樣做的)。所以你在疊加三角函數的不準確性。而且,由於您只計算與前一個角度的差異,因此我想您也正在疊加多次觸摸事件的不準確性。

如果是旋轉某物,那麼沒有理由使用三角或角度。你可以使用線性代數完全實現它。是這樣的:

v.x = touch.x - center.x; v.y = touch.y - center.y; 
float length = sqrt(v.x*v.x + v.y* v.y); 
if (length < 5) break; 
v.x /= length; v.y /= length; 

// the rotation matrix is 
// v.x -v.y 
// v.y v.x 

rot.x = previous.x * v.x + previous.y * v.y; 
rot.y = previous.x * v.y - previous.y * v.x; 

CGAffineTransform rotate = CGAffineTransformMake(rot.x, rot.y, -rot.y, rot.x, 0,0); 
... 
[view SetTransform:CGAffineTransformConcat (current, rotate)]; 
... 

previous.x = v.x; 
previous.y = v.y; 

此僞代碼計算當前點的歸一化向量(一個用於前一個點也被存儲的)。然後我們定義一個矩陣,將前一個向量旋轉到新的向量中。該矩陣與現有的轉換串聯在一起。

如果旋轉並不總是從前一狀態計算,而是從初始狀態計算,那將會更好。訣竅是僅爲達陣計算「前一個」。

+0

我編輯了我的問題。 – wczekalski 2012-01-07 09:11:45