Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Drag to rotate image only rotating one way

ianianianian Posts: 24Registered Users
edited February 2011 in iPhone SDK Development
Hi all,

I have this code nearly working, it's so close I can feeeeeel it...

However it only rotates clockwise (or ccw if I put I minus sign before the last = ).

Is there anything wrong with this that you can see?
	UITouch *oneTouch = [touches anyObject];
	CGPoint currentPoint = [oneTouch locationInView:self];
			
	double current_angle = [self wheelAngleFromPoint:currentPoint];
			
	self.value = current_angle * M_PI/180;
			
	self.transform = CGAffineTransformRotate(self.transform,self.value);

And the code to get the angle between the original touch and the current touch location (from a thread here):
- (double) wheelAngleFromPoint:(CGPoint)location
{
	double retAngle;
	
	
	location.x -= self.center.x;
	location.y = self.center.y;
	
	// normalize vector
	double vector_length = sqrt(location.x*location.x + location.y*location.y);
	
	location.x = location.x/vector_length;
	location.y = location.y/vector_length;
	
	retAngle = acos(location.y);
	
	if (location.x<0)
	{
		retAngle = -retAngle;
	}
	
	
	
	return retAngle;
}

Any ideas? Many thanks in advance,
Ian
Post edited by ianian on

Replies

  • ianianianian Posts: 24Registered Users
    edited March 2010
    Sorry to be rude and bump this, but it's the only bug preventing me from submitting my app...

    :)
  • smsawantsmsawant Posts: 82Registered Users
    edited February 2011
    ianian wrote: »
    Sorry to be rude and bump this, but it's the only bug preventing me from submitting my app...

    :)

    Were you able to solve this issue, i am looking for same feature.
    Can you please give some pointers for this? I really got stuck up on this.

    Thanks in Advance
    You can mail me at <a href="mailto:sanketsawant1@gmail.com">sanketsawant1@gmail.com</a>
  • ianianianian Posts: 24Registered Users
    edited February 2011
    smsawant wrote: »
    Were you able to solve this issue, i am looking for same feature.
    Can you please give some pointers for this? I really got stuck up on this.

    Thanks in Advance

    Well I don't remember what I did as this was AGES ago, but, I just found the project...

    MAYBE some of this code will be useful, it's not very well commented but it does work (though I don't know which bits you need, I can't remember :), please note this was my first ever iPhone app and the code, quickly looking at it now, is laughable in parts.
    // Return a point with respect to a given origin
    CGPoint centeredPoint(CGPoint pt, CGPoint origin)
    {
    	return CGPointMake(pt.x - origin.x, pt.y - origin.y);
    }
    
    // Return the angle of a point with respect to a given origin
    float getangle (CGPoint p1, CGPoint c1)
    {
    	// SOH CAH TOA 
    	CGPoint p = centeredPoint(p1, c1);
    	float h = ABS(sqrt(p.x * p.x + p.y * p.y));
    	float a = p.x;
    	float baseAngle = acos(a/h) * 180.0f / M_PI;
    	
    	// Above 180
    	if (p1.y > c1.y) baseAngle = 360.0f - baseAngle;
    	
    	return baseAngle;
    }
    
    // Return whether a point falls within the radius from a given origin
    BOOL pointInsideRadius(CGPoint p1, float r, CGPoint c1)
    {
    	CGPoint pt = centeredPoint(p1, c1);
    	float xsquared = pt.x * pt.x;
    	float ysquared = pt.y * pt.y;
    	float h = ABS(sqrt(xsquared + ysquared));
    	if (((xsquared + ysquared) / h) < r) return YES;
    	return NO;
    }
    
    
    @implementation DragView
    
    
    
    @synthesize value, propType, myImage, theta, binCircle;
    
    
    // Prepare the drag view
    - (id) initWithImage: (UIImage *) anImage
    {
    	
    	self.propType = @"Camera";
    	
    	if (self = [super initWithImage:anImage])
    	{
    		
    		self.userInteractionEnabled = YES;
    		self.multipleTouchEnabled = YES;
    		self.exclusiveTouch = NO;
    		originalTransform = CGAffineTransformIdentity;
    		
    	}
    	
    	
    	
    	
    	
    	return self;
    }
    
    - (double) wheelAngleFromPoint:(CGPoint)location
    {
    	double retAngle;
    	
    	location.x -= self.center.x;
    	location.y = self.center.y;
    	
    	// normalize vector
    	double vector_length = sqrt(location.x*location.x + location.y*location.y);
    	
    	location.x = location.x/vector_length;
    	location.y = location.y/vector_length;
    	
    	retAngle = acos(location.y);
    	
    	if (location.x<0)
    	{
    		retAngle = -retAngle;
    	}
    	
    	
    	
    	return retAngle;
    }
    
    
    
    
    
    
    // Apply touches to create transform
    - (void)updateOriginalTransformForTouches:(NSSet *)touches 
    {	
    	originalTransform = self.transform;
    }
    
    
    - (void) setPosition: (CGAffineTransform) pos
    {
    	
    	MoviePlayerAppDelegate *delegate = (MoviePlayerAppDelegate*)[[UIApplication sharedApplication] delegate];
    	
    	[[delegate.undoManager prepareWithInvocationTarget:self] setPosition:self.transform];
    	
    }
    
    // At start, store the touch begin points and set an original transform
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
    {
    	
    	CGPoint pt = [[touches anyObject] locationInView:self];
    	startLocation = pt;
    	
    	[self setPosition:self.transform];
    	
    	[super touchesBegan:touches withEvent:event];
    	
    	
    	//zooms up subview by 10% when touched.
    	[UIView beginAnimations:@"TouchDownAnimation" context:NULL];
    	[UIView setAnimationBeginsFromCurrentState:YES];
    	[UIView setAnimationDelegate:self];
    	[UIView setAnimationDidStopSelector:@selector(finishedTouchDownAnimation:finished:context:)];
    	[UIView setAnimationCurve:UIViewAnimationCurveLinear];
    	[UIView setAnimationDuration:0.15];
    	
    	
    	self.transform = CGAffineTransformScale(self.transform, 1.1, 1.1);
    	self.alpha = 0.85;
    	[UIView commitAnimations];
    	
    	for (UITouch *touch in touches) {
            if (touch.tapCount == 2) {
    			
    			//add graphic overlay over object (odd offset needed?)...
    			CGRect myImageRect = CGRectMake(self.center.x-62, self.center.y-88, 125, 125);
    			
    			
    			myImage = [[UIImageView alloc] initWithFrame:myImageRect];
    			[myImage setImage:[UIImage imageNamed:@"rotatecircle.png"]];
    			myImage.opaque = YES; // explicitly opaque for performance
    			
    			myImage.alpha = 0;
    			[self.window addSubview:myImage];
    			[self.window bringSubviewToFront:myImage];
    			
    			
    			myImage.transform = self.transform;
    			myImage.transform = CGAffineTransformScale(myImage.transform, 0.7, 0.7);
    			myImage.alpha = 100;
    			binCircle =@"1";
    			
    			
    			CGPoint cp = CGPointMake(self.bounds.size.width / 2.0f, self.bounds.size.height / 2.0f);
    			
    			//sets the angle based on the code above
    			self.theta = getangle([touch locationInView:self], cp);
    			
    		}
    		
    		if (touch.tapCount == 3) {
    			NSLog(@"Three touches! Go you!");
    		}
    		
    	}
    }
    
    
    
    - (void)finishedTouchDownAnimation:(NSString*)animationID finished:(BOOL)finished context:(void *)context {
    	
    	[UIView beginAnimations:nil context:NULL];
    	[UIView setAnimationBeginsFromCurrentState:YES];
    	[UIView setAnimationCurve:UIViewAnimationCurveLinear];
    	[UIView setAnimationDuration:0.15];
    	
    	self.transform = CGAffineTransformScale(self.transform, 0.910, 0.910);
    	self.alpha = 1.0;
    	[UIView commitAnimations];
    }
    
    // During movement, update the transform to match the touches
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
    {
    	
    	
    	[super touchesMoved:touches withEvent:event];
    	
    	
    	for (UITouch *touch in touches) {
            if (touch.tapCount < 2) {
    			
    			CGPoint pt = [[touches anyObject] locationInView:self];
    			float dx = pt.x - startLocation.x;
    			float dy = pt.y - startLocation.y;
    			
    			self.transform = CGAffineTransformTranslate(self.transform, dx, dy);
    			
    			
    		}
    		
            if (touch.tapCount == 2) {
    			
    			CGPoint cp = CGPointMake(self.bounds.size.width / 2.0f, self.bounds.size.height / 2.0f);
    			
    			
    			float newtheta = getangle([touch locationInView:self], cp);
    			float dtheta = newtheta - self.theta;
    			
    			
    			int ntimes = 0;
    			while ((ABS(dtheta) > 300.0f)  && (ntimes++ < 4))
    				if (dtheta > 0.0f) dtheta -= 360.0f; else dtheta += 360.0f;
    			
    			
    			self.value -= dtheta / 360.0f;
    			self.theta = newtheta;
    			self.transform = CGAffineTransformRotate(self.transform,self.value*5);
    			
    			
    			
    		}
    		
    		
    	}
    }
    
    
    // Finish by removing touches, handling double-tap requests
    // This removes the rotation graphic.
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
    {
    	
    	
        [self updateOriginalTransformForTouches:[event touchesForView:self]];
    	
    	if ([binCircle isEqualToString:@"1"]) {
    		[myImage removeFromSuperview];
    		binCircle =@"0";
    		[myImage autorelease];
    	}
    	
        for (UITouch *touch in touches) {
            if (touch.tapCount > 1) {
    			
    			
                [self.superview bringSubviewToFront:self];
    			
    			NSLog(@"Removing rotate circle");
    			
            }
    		
    		
        }
    	
    }
    
    // Redirect cancel to ended
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 
    {
        [self touchesEnded:touches withEvent:event];
    }
    
    
    
    - (void)dealloc {
    	
    	if (touchBeginPoints) CFRelease(touchBeginPoints);
    	[super dealloc];
    }
    
    
    @end
    
    
Sign In or Register to comment.