0

I'm trying to rotate image(triangle) to align it to gravity. So that one corner is always down. But nothing helps. Triangle going mad.

double accelX = motion.userAcceleration.x;
double accelY = motion.userAcceleration.y;
rollingX = (accelX * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor));
rollingY = (accelY * kFilteringFactor) + (rollingY * (1.0 - kFilteringFactor));
accelX = accelX - rollingX;
accelY = accelY - rollingY;
float angle = atan2(accelY, accelX);

[rootLayer setAnchorPoint:CGPointMake(0.5, 0.5)];
CATransform3D rotation = CATransform3DIdentity;
rotation.m34 = 1.0f / -500.0f;
rotation = CATransform3DRotate(rotation, angle, 0.0f, 0.0f, 1.0f);
rootLayer.sublayerTransform = rotation;
Oleg Korban
  • 249
  • 3
  • 14

1 Answers1

0

Asssuming that motion refers to an instance of CMDeviceMotion, you should use the gravity property instead of user acceleration. Then you have to use the gravity vector directly i.e. without any filtering. It's the easiest and recommended way as it uses gyroscope as well to enhance the precision.

If you are bound to use pure accelerometer data because you want to support older devices that do not have a gyroscope, you have to use CMMotionManager's accelerometerData property. But there's a little bug. The code applies a high-pass filter to accelX and accelY instead of a low-pass filter. So it should look like:

double accelX = motionManager.accelerometerData.acceleration.x;
double accelY = motionManager.accelerometerData.acceleration.y;
rollingX = (accelX * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor));
rollingY = (accelY * kFilteringFactor) + (rollingY * (1.0 - kFilteringFactor));
float angle = atan2(rollingY, rollingX);

with filteringFactor <= 0.3

Kay
  • 12,918
  • 4
  • 55
  • 77
  • Thanks. I have already tried with CMGyroData, but no luck. CMGyroData *gyroData = [_notification.userInfo objectForKey:@"gyroNotification"]; CMRotationRate rotate = gyroData.rotationRate; CATransform3D rotation = rootLayer.sublayerTransform; rotation.m34 = 1.0f / -500.0f; rotation = CATransform3DRotate(rotation, rotate.y, 0.0f, 0.0f, 1.0f);rootLayer.sublayerTransform = rotation; – Oleg Korban Aug 10 '12 at 09:19