Go Back   MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Nov 12, 2009, 08:11 AM   #1
blueeye
macrumors member
 
Join Date: Oct 2007
Problem moving UIView with touches

Hi all,

I'm trying to build an object which lets you "grab" a corner with your finger and move it around as if it were a real object (it would rotate and translate depending on where you grabbed it and moved to).

For some reason, though the rotation works fine and in theory the translation seems to work fine as well, the object does not move as much as it should (so the touch slowly gains distance between itself and the object) and the object seems to jump between two positions as it moves making it almost seem as if there are two (because it flickers with surprising frequency).

I'll post the relevant methods here:

Code:
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	NSLog(@"Touches began on Physical Object");
	if([touches count] == 1) {
		UITouch * touch = [[touches allObjects] objectAtIndex:0];
		self.throwStartLocation = [touch locationInView:[self superview]];
		NSLog(@"Touch location: (%f, %f)", self.throwStartLocation.x, self.throwStartLocation.y);
		self.throwStartTime = [touch timestamp];
		
		self.touchBearingFromCentre = [self calculateBearingFromCentre:self.throwStartLocation];
	}
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
	if([touches count] == 1) {
		UITouch * touch = [[touches allObjects] objectAtIndex:0];
		CGPoint touchLocation = [touch locationInView:[self superview]];
		
		//Get new bearings
		Bearing2D bearing = [self calculateBearingFromCentre:touchLocation];
		
		//Calculate required translation
		float trans = bearing.distance - self.touchBearingFromCentre.distance;
		float tx = trans * sinf(bearing.angle);
		float ty = - (trans * cosf(bearing.angle));
	
		self.center = CGPointMake(self.center.x+tx, self.center.y+ty);
		
		//Calculate required rotation
		self.transform = CGAffineTransformRotate(self.transform, bearing.angle - self.touchBearingFromCentre.angle);
		
		//Set saved positions to current touch positions
		self.throwStartLocation = touchLocation;
		self.throwStartTime = [touch timestamp];
		self.touchBearingFromCentre = bearing;
	}
}

- (Bearing2D) calculateBearingFromCentre: (CGPoint) touchLocation {
	CGPoint centre = self.center;

	Bearing2D bearing;
	bearing.distance = distanceBetweenTwoPoints2D(centre, touchLocation);
	float angle = asinf(ABS(touchLocation.x - centre.x)/bearing.distance);
	
	BOOL TOP = (touchLocation.y <= centre.y);
	BOOL LEFT = (touchLocation.x <= centre.x);
	
	if(TOP && !LEFT) {
		//Top Right Quadrant
		bearing.angle = angle;
	} else if (!TOP && !LEFT) {
		//Bottom Right Quadrant
		bearing.angle = (M_PI- angle);
	} else if (!TOP && LEFT) {
		//Bottom Left Quadrant
		bearing.angle = M_PI + angle;
	} else if(TOP && LEFT) {
		//Top Left Quadrant
		bearing.angle = 2*M_PI - angle;
	}
	
	NSLog(@"Touch is at a bearing of %f and a distance of %f from centre at (%f, %f)", bearing.angle, bearing.distance, centre.x, centre.y);
	return bearing;
}
Bearing2D is just a struct containing distance and angle data (floats). Bearings are taken from "North" (the top direction of the screen) as is the convention. All angles are in radians.

Any help would be much appreciated.
blueeye is offline   0 Reply With Quote
Old Nov 12, 2009, 08:59 AM   #2
blueeye
Thread Starter
macrumors member
 
Join Date: Oct 2007
I don't know if this helps but I logged the centre of the UIView and also tx and ty as follows (in the touchesMoved method):

Code:
float trans = bearing.distance - self.touchBearingFromCentre.distance;
float tx = trans * sinf(bearing.angle);
float ty = -(trans * cosf(bearing.angle));

NSLog(@"%f %f %f %f", self.center.x, self.center.y, tx, ty);
The output shows two pairs of translations being calculated very quickly together. The translation values are almost negatives of each other which might explain the flickering. The output looks as follows (sample):

Code:
2009-11-12 14:58:19.294 DocThrow[7604:207] 175.810349 210.684875 3.826098 6.233794
2009-11-12 14:58:19.303 DocThrow[7604:207] 179.636444 216.918671 -0.223187 -0.384551
2009-11-12 14:58:19.314 DocThrow[7604:207] 179.413254 216.534119 4.245363 7.671549
2009-11-12 14:58:19.323 DocThrow[7604:207] 183.658615 224.205673 -0.175163 -0.331645
2009-11-12 14:58:19.343 DocThrow[7604:207] 183.483444 223.874023 3.362693 6.688859
2009-11-12 14:58:19.355 DocThrow[7604:207] 186.846130 230.562881 -0.131342 -0.274367
2009-11-12 14:58:19.369 DocThrow[7604:207] 186.714783 230.288513 3.138061 6.867931
2009-11-12 14:58:19.382 DocThrow[7604:207] 189.852844 237.156448 -0.098292 -0.225313
2009-11-12 14:58:19.397 DocThrow[7604:207] 189.754547 236.931137 3.269465 7.875489
2009-11-12 14:58:19.413 DocThrow[7604:207] 193.024017 244.806625 -1.107775 -2.758256
2009-11-12 14:58:19.429 DocThrow[7604:207] 191.916245 242.048370 2.776053 7.096982
2009-11-12 14:58:19.445 DocThrow[7604:207] 194.692291 249.145355 -1.390990 -3.633013
2009-11-12 14:58:19.461 DocThrow[7604:207] 193.301300 245.512344 2.679798 7.144592
2009-11-12 14:58:19.478 DocThrow[7604:207] 195.981094 252.656937 -2.003174 -5.397062
2009-11-12 14:58:19.495 DocThrow[7604:207] 193.977921 247.259872 2.319129 6.280084
2009-11-12 14:58:19.511 DocThrow[7604:207] 196.297043 253.539963 -1.888470 -5.068898
2009-11-12 14:58:19.527 DocThrow[7604:207] 194.408569 248.471069 2.672719 7.149411
2009-11-12 14:58:19.543 DocThrow[7604:207] 197.081284 255.620483 -2.238668 -5.936920
2009-11-12 14:58:19.557 DocThrow[7604:207] 194.842621 249.683563 2.712987 7.135958
This is weird because the translation values seem to occur in pairs of negative and positive ones.
blueeye is offline   0 Reply With Quote
Old Nov 12, 2009, 09:40 AM   #3
blueeye
Thread Starter
macrumors member
 
Join Date: Oct 2007
I've narrowed it down to what I think is the cause of the problem. The trans value, which calculates the difference between the distances of the touches from the centre of the UIView rapidly flickers between positive and negative. This could be due to an inaccuracy in using one's finger? I'm sure that what I'm trying to do has been done before, however, so I'm wondering how I would programme around this.

Any ideas?

(for reference, trans is set as follows)

Code:
float trans = bearing.distance - self.touchBearingFromCentre.distance;
self.touchBearingFromCentre is set from the previous touch.
blueeye is offline   0 Reply With Quote
Old Nov 12, 2009, 10:10 AM   #4
blueeye
Thread Starter
macrumors member
 
Join Date: Oct 2007
I solved the problem. I used [touch previousLocationInView:[self superview]] and now it works, beautifully.
blueeye is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Question about touches that begin in a UIView's frame and end in its child's. moonman239 iPhone/iPad Programming 4 Feb 23, 2014 11:49 AM
Problem with moving from iPhone4 to iPhone5 piatti iPhone 3 Jan 5, 2013 02:14 AM
Problem with user touches the marker on image in image targets srilatha iPhone 0 Oct 2, 2012 01:33 AM
Cursor moving backwards when typing problem Rockoar OS X 10.8 Mountain Lion 3 Sep 9, 2012 04:50 PM
make uiview transparent without having the uiview's buttons transparent johnmerlino iPhone/iPad Programming 7 Jun 1, 2012 02:20 AM

Forum Jump

All times are GMT -5. The time now is 07:18 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC