2009-03-20 33 views
11

Tôi đang cố gắng phát hiện tốc độ di chuyển cảm ứng và tôi không phải lúc nào cũng nhận được kết quả mong đợi. (thêm: Tốc độ tăng vọt quá nhiều) Có ai có thể phát hiện ra nếu tôi đang làm điều gì đó sôi nổi hoặc đề xuất cách làm tốt hơn?Phát hiện tốc độ di chuyển UITouch


- (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); 

} 

Trả lời

10

Bạn có thể thử (zero ra distanceSinceStart và timeSinceStart trong touchesBegan):

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

mà sẽ cung cấp cho bạn tốc độ trung bình kể từ khi bạn bắt đầu cảm ứng (tổng khoảng cách/tổng thời gian).

Hoặc bạn có thể làm một trung bình trượt của tốc độ, có lẽ một mũ di chuyển trung bình:

const float lambda = 0.8f; // the closer to 1 the higher weight to the next touch 

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

Bạn có thể điều chỉnh lambda để giá trị gần 1 nếu bạn muốn sẽ chú ý hơn đến giá trị mới.

+0

Này ... tôi đang gặp sự cố khi triển khai điều này. Là một phần chức năng lambda của mục tiêu-c? Tôi cần gì để thực hiện nó? tia – dizy

+2

Không ... đó là hằng số bạn chỉ định chính mình. Càng gần đến 1, bạn càng đặt trọng lượng lên giá trị mới nhất. So sánh với trung bình số học của các giá trị n. Mỗi giá trị mới có trọng số là 1/n. Đối với hàm mũ, đặt lambda = 2/(n + 1) trong đó n là giá trị số học tương đương. Vì vậy, giá trị mới là trọng số 2/(n + 1) thay vì 1/n, và sau đó trung bình di chuyển hiện tại được thu nhỏ lại bởi (1-lambda) = (n-1)/(n + 1) và hai là thêm. Clearer? – Jim

3

Vấn đề chính là tính toán tốc độ sẽ rất không chính xác khi timeSincePrevious là rất nhỏ (một vài phần nghìn giây). Để thấy điều này, giả sử rằng timeSincePrevious là 1ms. Sau đó tốc độ tính toán sẽ là 0 nếu distanceFromPrevious là 0, và 1000 nếu distanceFromZero là 1.

Vì lý do này, tôi đề nghị giá trị sau đây của lambda:

const float labmda = (timeSincePrevious>0.2? 1: timeSincePrevious/0.2); 

Đó là để nói rằng, chúng tôi sử dụng một lambda nhỏ khi timeSincePrevious là nhỏ.

+0

Đây là câu trả lời duy nhất sử dụng bộ lọc tỷ lệ mẫu biến thích hợp. Và để làm điều đó như một thông thấp đầu tiên theo tiêu chuẩn: k = ; a = exp (-dt/k); filterSpeed ​​= a * (dx/dt) + (1-a) * được lọc; – kylefinn

1

Đề xuất bộ lọc có thể là ok, nhưng nó không giải quyết được vấn đề: đỉnh sẽ được làm mịn, nhưng vẫn còn.

Nếu bạn đăng xuất các sự kiện chạm, các đỉnh này sẽ trông giống như một lần chạm với đồng bằng thời gian rất ít so với trước đó (0,001215 ms), trước đó bằng cách chạm vào đồng bằng thời gian lớn.

 
distance = 17.269917, timeDelta = 0.016132, speed = 1070.504639 
distance = 15.206906, timeDelta = 0.017494, speed = 869.251709 
distance = 15.882380, timeDelta = 0.017583, speed = 903.297546 
distance = 14.983324, timeDelta = 0.030101, speed = 497.771088  //low peak 
distance = 15.435349, timeDelta = 0.001215, speed = 12703.991211 //high peak! 
distance = 15.882380, timeDelta = 0.017343, speed = 915.795898 
distance = 15.890248, timeDelta = 0.016302, speed = 974.742249 
distance = 16.560495, timeDelta = 0.016468, speed = 1005.606445 
distance = 16.101242, timeDelta = 0.017291, speed = 931.201050 

Những gì tôi làm là tính toán một đồng bằng thời gian trung bình giữa các sự kiện liên lạc gần đây, và nếu có một liên lạc với đồng bằng thời gian bất thường (± 30%), tôi bỏ qua tốc độ của nó (giữ tốc độ của sự kiện trước đó)

Các vấn đề liên quan