views:

1178

answers:

1

I'm trying to detect the speed of touch movement and i'm not always getting the results I'd expect. (added: Speed spikes around too much) Can anyone spot if i'm doing something funky or suggest a better way of doing it ?


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    self.previousTimestamp = event.timestamp;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self.view];
    CGPoint prevLocation = [touch previousLocationInView:self.view];
    CGFloat distanceFromPrevious = distanceBetweenPoints(location,prevLocation);
    NSTimeInterval timeSincePrevious = event.timestamp - self.previousTimestamp;
    CGFloat speed = distanceFromPrevious/timeSincePrevious;
    self.previousTimestamp = event.timestamp;
    NSLog(@"dist %f | time %f | speed %f",distanceFromPrevious, timeSincePrevious, speed);

}

+3  A: 

You could try (zero out distanceSinceStart and timeSinceStart in touchesBegan):

distanceSinceStart = distanceSinceStart + distanceFromPrevious;
timeSinceStart = timeSincestart + timeSincePrevious;
speed = distanceSinceStart/timeSinceStart;

which will give you the average speed since you started the touch (total distance/total time).

Or you could do a moving average of the speed, perhaps an exponential moving average:

newSpeed = (1.0 - lambda) * oldSpeed + lambda* (distanceFromPrevious/timeSincePrevious);
oldSpeed = newSpeed;

You can adjust lambda to values near 1 if you want to give more weight to recent values.

Jim
Hey... i'm having trouble implementing this. Is lambda function part of objective-c ? What do I need to implement it ? tia
dizy
Nope...it's a constant you specify yourself. The closer it is to 1, the more weight you place on the newest value. Compare to an arithmetic average of n values. Each new value gets a weight of 1/n.For exponential, set lambda = 2/(n+1) where n is the equivalent arithmetic value. So the new value is weighted 2/(n+1) instead of 1/n, and then the existing moving average is scaled back by (1-lambda) = (n-1)/(n+1) and the two are added.Clearer?
Jim