IOS using an accelerometer to move an object in a circle

I am trying to use the accelerometer to move the image in a circle. I have a problem when the image hits the edge of the circle, it just moves the other side of the circle. My code is below:

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { //NSLog(@"x : %g", acceleration.x); //NSLog(@"y : %g", acceleration.y); //NSLog(@"z : %g", acceleration.z); delta.x = acceleration.x * 10; delta.y = acceleration.y * 10; joypadCap.center = CGPointMake(joypadCap.center.x + delta.x, joypadCap.center.y - delta.y); distance = sqrtf(((joypadCap.center.x - 160) * (joypadCap.center.x - 160)) + ((joypadCap.center.y -206) * (joypadCap.center.y - 206))); //NSLog(@"Distance : %f", distance); touchAngle = atan2(joypadCap.center.y, joypadCap.center.x); NSLog(@"Angle : %f", touchAngle); if (distance > 50) { joypadCap.center = CGPointMake(160 - cosf(touchAngle) * 50, 206 - sinf(touchAngle) * 50); } 
+4
source share
1 answer

I had the same problem when trying to implement a circular spirit level using CMDeviceMotion. I found that this is a problem with the coordinates passed to atan2(y,x) . This function requires Cartesian coordinates, with (0,0) in the center of the view. However, the screen coordinates are (0,0) in the upper left corner. I created methods for converting a point between two coordinate systems, and now it works well.

I posted an example project here on github, but here is the most important part:

 float distance = sqrtf(((point.x - halfOfWidth) * (point.x - halfOfWidth)) + ((point.y - halfOfWidth) * (point.y - halfOfWidth))); if (distance > maxDistance) { // Convert point from screen coordinate system to cartesian coordinate system, // with (0,0) located in the centre of the view CGPoint pointInCartesianCoordSystem = [self convertScreenPointToCartesianCoordSystem:point inFrame:self.view.frame]; // Calculate angle of point in radians from centre of the view CGFloat angle = atan2(pointInCartesianCoordSystem.y, pointInCartesianCoordSystem.x); // Get new point on the edge of the circle point = CGPointMake(cos(angle) * maxDistance, sinf(angle) * maxDistance); // Convert back to screen coordinate system point = [self convertCartesianPointToScreenCoordSystem:point inFrame:self.view.frame]; } 

AND:

 - (CGPoint)convertScreenPointToCartesianCoordSystem:(CGPoint)point inFrame:(CGRect)frame { float x = point.x - (frame.size.width / 2.0f); float y = (point.y - (frame.size.height / 2.0f)) * -1.0f; return CGPointMake(x, y); } - (CGPoint)convertCartesianPointToScreenCoordSystem:(CGPoint)point inFrame:(CGRect)frame { float x = point.x + (frame.size.width / 2.0f); float y = (point.y * -1.0f) + (frame.size.height / 2.0f); return CGPointMake(x, y); } 
+4
source

Source: https://habr.com/ru/post/1438121/


All Articles