движение акселерометра iPhone не работает гладко - PullRequest
1 голос
/ 29 марта 2011

Мне нужно реализовать приложение для акселерометра 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);

}

1 Ответ

1 голос
/ 11 декабря 2013

Мне это тоже показалось немного разочаровывающим, потому что этот фильтр, который вы используете (который довольно распространен), похоже, не работает так хорошо, как вы ожидаете.В конце я решил вычислить средневзвешенное значение для последних 8 образцов акселерометра и использовать его в качестве конечного значения.

проблема заключается в том, что чем больше я взвешиваю старые образцы, тем более плавным будет конечное движение, но задержка будет ощущаться яснее.С другой стороны - чем больше я взвешиваю новые сэмплы - последние движения будут более грязными, но более точными (задержка будет ощущаться все меньше и меньше).

Мое решение состояло в том, чтобы значительно взвесить средние образцыбольше, чем новый или старый, и создать весовую пирамиду.Я обнаружил (не знаю почему, кто-то может объяснить?), Что биномиальный вес Ньютона - лучший.

Проще говоря, в любой момент я добавляю коэффициент дублирования к каждой из последних 8 выборок в соответствии с этим массивом: 1;7;21;35;35;21;7; 1 (значения легко найти с помощью треугольника Паскаля: 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;

s даст вам значение, которое вы должны установить в newX.

сделать то же самое для y и z, чтобы получить полное значение движения.

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...