CGAffineTranformRotate atan2不准确

我正在进行我的视图转换,总是发生奇怪的事情,我的意思是我用这个代码计算angular度: angle = atan2f(currentTouchPoint.y - center.y, currentTouchPoint.x - center.x) - atan2f(previousTouchPoint.y - center.y, previousTouchPoint.x - center.x);

视图旋转但不正确。 我的意思是它在正确的方向旋转,但angular度总是不准确的+/- 0.05弧度。 而当我再次点击时,视图旋转到适当的位置 。 任何adivices? 逗号后的angular度精确到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。 圆有子视图 – CircleThumbs。 拇指代表圈的单个部分。 积分计算正确,但我不会解释为什么,因为没有必要。

阿坦计算从来不是完全正确的。 而你让iOS再次计算cos和sin的angular度(cgaffinetransformRotate是这样做的)。 所以你正在叠加三angular测量误差。 而且,由于您只计算与前一个angular度的差异,因此我想您也正在叠加多次触摸事件的不准确性。

如果是旋转的东西,那么没有理由使用三angular或angular度。 您可以使用线性代数完全实现这一点。 像这样的东西:

 vx = touch.x - center.x; vy = touch.y - center.y; float length = sqrt(vx*vx + vy* vy); if (length < 5 ) break; vx /= length; vy /= length; // the rotation matrix is // vx -vy // vy vx rot.x = previous.x * vx + previous.y * vy; rot.y = previous.x * vy - previous.y * vx; CGAffineTransform rotate = CGAffineTransformMake( rot.x, rot.y, -rot.y, rot.x, 0,0); ... [view SetTransform:CGAffineTransformConcat ( current, rotate )]; ... previous.x = vx; previous.y = vy; 

这个伪代码为当前点计算一个归一化的vector(前一个点的vector也被存储)。 然后我们定义一个matrix,将前一个向量旋转到新的向量中。 该matrix与现有的转换串联在一起。

如果旋转不是总是从前一个状态计算出来,而是从一个初始状态计算出来,那就更好了。 诀窍是只计算触地下的“前”。