我必须实现一个iPhone加速度计应用程序,我必须根据加速度计坐标移动图像。我的应用程序运行良好但有时我的ImageView移动到顶部(查看y)然后消失。
我使用了以下代码,
UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = 1.0f/30.f;
#define kFilteringFactor 0.1
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
static UIAccelerationValue rollingX = 0.0;
static UIAccelerationValue rollingY = 0.0;
// Subtract the low-pass value from the current value to get a simplified high-pass filter
rollingX = (acceleration.x * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor));
rollingY = (acceleration.y * kFilteringFactor) + (rollingY * (1.0 - kFilteringFactor));
double accelX = acceleration.x - rollingX;
double accelY = acceleration.y - rollingY;
// Use the acceleration data.
float newX = containerView.center.x + ((float)accelX * 30.0f);
float newY = containerView.center.y + ((float)accelY * 30.0f);
containerView.center = CGPointMake(newX, newY);
}
答案 0 :(得分:1)
我发现它有点令人沮丧,因为你正在使用的这个过滤器(这很常见)似乎并没有像你期望的那样完成工作。 最后,我决定计算加速度计最后8个样本的加权平均值,并将其作为最终值。
问题是:我对旧样本的重量越大 - 最终的运动会更顺畅,但延迟会更清晰。另一方面 - 我对新样本的权重越大 - 最终的动作会更脏,但更精确(延迟会越来越少)。
我的解决方案是对中间样本的重量远远超过新旧样本,并创建一个权重金字塔。我发现(不知道为什么,有人可以解释一下吗?)牛顿的二项式重量是最好的。
简单来说,在任何时候,我根据这个数组为最后8个样本中的每一个添加一个重复因子:1; 7; 21; 35; 35; 21; 7; 1(使用Pascal三角形很容易找到这些值:http://www.mathsisfun.com/pascals-triangle.html)。
代码如下所示:
if ([d count]<8) {
[d addObject:[NSNumber numberWithFloat:acceleration.x]];
}
else{
[d removeObjectAtIndex:0];
[d addObject:[NSNumber numberWithFloat:acceleration.x]];
}
NSMutableArray*binom=[[NSMutableArray alloc] init];
[binom addObject:[NSNumber numberWithInt:1]];
[binom addObject:[NSNumber numberWithInt:7]];
[binom addObject:[NSNumber numberWithInt:21]];
[binom addObject:[NSNumber numberWithInt:35]];
[binom addObject:[NSNumber numberWithInt:35]];
[binom addObject:[NSNumber numberWithInt:21]];
[binom addObject:[NSNumber numberWithInt:7]];
[binom addObject:[NSNumber numberWithInt:1]];
float s=0;
int j=0;
for (NSNumber* n in d){
s+=[n floatValue]*[[binom objectAtIndex:j] intValue];
j++;
}
s=s/128;
将为您提供应在newX中设置的值。
对y和z执行相同操作,以获得完整的移动值。
希望有所帮助