我正在通过触摸,拖动和释放来旋转UIImageView。我正在通过函数旋转对象:
-(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 :(得分:0)
我不熟悉iPhone,但这通常是由于累积舍入错误(如果corner.x
/ corner.y
是整数,尤为明显)。 / p>
要修复,而不是每个帧再次旋转一个旋转的矩形(或每次用户触摸屏幕时,或其他任何东西),你只存储矩形原始方向的角度偏移并每帧重新计算新坐标。
答案 1 :(得分:0)
正如BlueRaja所说,数学不准确 - 它本身就是近似的,而你正在积累错误。您需要每次从图层的绝对尺寸和旋转重新计算角点的位置,而不是尝试跟踪它。
幸运的是,CALayer可以为您做到这一点而不会有太多麻烦
ptInLayerCoords = [bottle.layer convertPoint:pt fromLayer:self.layer];
didHit = [layer containsPoint:ptInLayerCoords];