what i have here works exactly how i want it. My question is that it seems overly complex, is there a faster/better way of doing the pitchAngleRadians calculations i am showing below?
the code is shown... (along with two images)
the first image is how the atan2 calculation comes out of the iPad naturally, "pitchAngleRadians = atan2(accel[0], accel2);" (what the accelerometer puts out normally)
what i want is to shift "Zero" to a new degree angle, in the second image i've shifted it a -135 degrees as an example. (everything in code is radians) so for instance the variable "pitchNeutralAngle" in this example is the radian equivalent of (-135) degrees
this code produces exactly what i want for the variable "pitchAngleRadians", which is the second image, but seems too long, and this code is in a tight run loop, so it would speed up if i can get this cleaner/faster.
i go through an intermediate step of "ranging" the degrees between 0 and 360, so that crossing the boarder of 180 degrees does not mess up the calculation, however i still have to get it back to the 0 to 180 form, so that is what the next calculation is.
i've tested this code a little bit, and it does appear to work.
//------------------------------------------------------------------------------------
- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
accel[0] = (acceleration.x * kFilteringFactor) + accel[0] * (1.0 - kFilteringFactor);
accel[1] = (acceleration.y * kFilteringFactor) + accel[1] * (1.0 - kFilteringFactor);
accel[2] = (acceleration.z * kFilteringFactor) + accel[2] * (1.0 - kFilteringFactor);
pitchAngleRadians = (atan2(accel[0], accel[2]) - pitchNeutralAngle);
pitchAngleRadians = pitchAngleRadians - floorf(pitchAngleRadians/6.28318f)*6.28318f;
if (pitchAngleRadians > 3.14159) pitchAngleRadians = -6.28318f + pitchAngleRadians;
//float a = atan2(acce开发者_Go百科l[0], accel[2]);
//NSLog(@"a = %f", a);
}
Are you bound to old 3.x devices or can you rely on iOS 4.x? In general the "old" UIAccelerometerDelegate will be deprecated soon because it is replaced by new Core Motion framework (s. Why is accelerometer:didAccelerate: deprecated in IOS5?)
Next, you are talking about iPad which has IMO a gyroscope (or is it iPad 2 only?). If you can rely on devices having one, you are done with Core Motion DeviceMotion which provides Euler angles ready to use without any problems (OK bear in mind Gimbal lock). See Simple iPhone motion detect especially:
- CMMotionManager startDeviceMotionUpdatesToQueue:withHandler:
- CMDeviceMotionHandler
- CMDeviceMotion attitude
- CMAttitude pitch
- Event Handling Guide for iOS / Handling Processed Device-Motion Data
You can check out WWDC2010 sample code: WWDC 2010 Sample Code
If not, any chance to convince you or your business partners? OK, you are still there :-) hmmh, atan and atan2 have some discontinuities, are you sure that it works out for all combinations of small x and y values i.e. if the device is lying on the table without or with just small motion but some sensor noise?
Regarding perfomance: Yes atan is quite expensive so you can check out using alternatives like FastMath.h (it's in French but no worries follow the link at C++ en un simple fichier header FastMath.h contenant.
精彩评论