CGAffineTransformMakeRotation идет в другую сторону после 180 градусов (-3,14)
Так,
я пытаюсь сделать очень простое вращение диска (2d), в зависимости от прикосновения пользователя к нему, как у диджея или чего-то еще. Это работает, но есть проблема, после определенного количества вращения, оно начинает двигаться назад, это значение после 180 градусов или, как я видел во время регистрации угла, -3,14 (пи).
Мне было интересно, как я могу достичь бесконечного цикла, я имею в виду, пользователь может продолжать вращаться и вращаться в любую сторону, просто скользя пальцем? Также второй вопрос, есть ли способ ускорить вращение?
Вот мой код прямо сейчас:
#import <UIKit/UIKit.h>
@interface Draggable : UIImageView {
CGPoint firstLoc;
UILabel * fred;
double angle;
}
@property (assign) CGPoint firstLoc;
@property (retain) UILabel * fred;
@end
@implementation Draggable
@synthesize fred, firstLoc;
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
angle = 0;
if (self) {
// Initialization code
}
return self;
}
-(void)handleObject:(NSSet *)touches
withEvent:(UIEvent *)event
isLast:(BOOL)lst
{
UITouch *touch =[[[event allTouches] allObjects] lastObject];
CGPoint curLoc = [touch locationInView:self];
float fromAngle = atan2( firstLoc.y-self.center.y,
firstLoc.x-self.center.x );
float toAngle = atan2( curLoc.y-(self.center.y+10),
curLoc.x-(self.center.x+10));
float newAngle = angle + (toAngle - fromAngle);
NSLog(@"%f",newAngle);
CGAffineTransform cgaRotate = CGAffineTransformMakeRotation(newAngle);
self.transform = cgaRotate;
if (lst)
angle = newAngle;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch =[[[event allTouches] allObjects] lastObject];
firstLoc = [touch locationInView:self];
};
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self handleObject:touches withEvent:event isLast:NO];
};
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self handleObject:touches withEvent:event isLast:YES];
}
@end
И в ViewController:
UIImage *tmpImage = [UIImage imageNamed:@"theDisc.png"];
CGRect cellRectangle;
cellRectangle = CGRectMake(-1,self.view.frame.size.height,tmpImage.size.width ,tmpImage.size.height );
dragger = [[Draggable alloc] initWithFrame:cellRectangle];
[dragger setImage:tmpImage];
[dragger setUserInteractionEnabled:YES];
dragger.layer.anchorPoint = CGPointMake(.5,.5);
[self.view addSubview:dragger];
Я открыт для новых / более чистых / более правильных способов сделать это тоже.
Заранее спасибо.
2 ответа
Переверните угол, если он ниже -180 или выше 180 градусов. Рассмотрим следующее touchesMoved
реализация:
@implementation RotateView
#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
CGFloat angleBetweenLinesInDegrees(CGPoint beginLineA, CGPoint endLineA, CGPoint beginLineB, CGPoint endLineB)
{
CGFloat a = endLineA.x - beginLineA.x;
CGFloat b = endLineA.y - beginLineA.y;
CGFloat c = endLineB.x - beginLineB.x;
CGFloat d = endLineB.y - beginLineB.y;
CGFloat atanA = atan2(a, b);
CGFloat atanB = atan2(c, d);
// convert radians to degrees
return (atanA - atanB) * 180 / M_PI;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint curPoint = [[touches anyObject] locationInView:self];
CGPoint prevPoint = [[touches anyObject] previousLocationInView:self];
// calculate rotation angle between two points
CGFloat angle = angleBetweenLinesInDegrees(self.center, prevPoint, self.center, curPoint);
// Flip
if (angle > 180) {
angle -= 360;
} else if (angle < -180) {
angle += 360;
}
self.layer.transform = CATransform3DRotate(self.layer.transform, DEGREES_TO_RADIANS(angle), .0, .0, 1.0);
}
@end
При перемещении по внешним границам вида он будет вращаться непрерывно, как вращающееся колесо. Надеюсь, поможет.
У вас есть некоторые проблемы здесь:
1)
CGPoint curLoc = [touch locationInView:self];
а также
firstLoc = [touch locationInView:self];
Вы трансформируете свое представление, а затем спрашиваете, где находится прикосновение. Вы не можете получить правильное местоположение касания в повернутом виде. Сделайте их чем-то не преобразованным (например self.superview
после того, как положить его в контейнер)
2-)
cellRectangle = CGRectMake(-1,self.view.frame.size.height,tmpImage.size.width ,tmpImage.size.height );
Вы помещаете свой Draggable экземпляр с экрана, передавая self.view.frame.size.height
как CGRect
"s y
параметр.