blob: c4551ccf1a28fffe984fcc07f0da4c9784a41ba9 [file] [log] [blame]
// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "touch_noise_filter/far_apart_taps_filter.h"
#include <base/macros.h>
#include <cmath>
#include <cstddef>
#include <cstdio>
namespace touch_noise_filter {
namespace {
// Minimum squared distance between taps to be considered far apart.
__s32 kMinDistance2 = 1500 * 1500;
// Max time between taps considered.
double kMaxTapDeltaSecs = 0.03;
// Maximum squared movement of a touch to still be considered a tap.
__s32 kMaxTapMovement2 = 20 * 20;
// Returns the squared distance between (x1, y1) and (x2, y2).
__s32 Distance2(__s32 x1, __s32 y1, __s32 x2, __s32 y2) {
return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
}
} // namespace {}
void FarApartTapsFilter::FilterFrame(Frame* previous, Frame* current,
size_t num_slots) {
// Remove old taps and touches moving more than min delta.
double tapCutoff = current->timestamp_ - kMaxTapDeltaSecs;
for (size_t i = 0; i < num_slots; i++) {
if (tracked_taps_[i].start_ < tapCutoff)
tracked_taps_[i].start_ = 0;
}
for (size_t slot = 0; slot < num_slots; slot++) {
Finger* cur = &current->fingers_[slot];
Finger* prev = &previous->fingers_[slot];
// Only look at slots with active touches.
if (cur->tracking_id_ == -1 && prev->tracking_id_ == -1)
continue;
bool arrived = prev->tracking_id_ == -1 && cur->tracking_id_ > 0;
bool departing = prev->tracking_id_ >= 0 && cur->tracking_id_ == -1;
if (arrived) {
// Track new finger info.
tracked_taps_[slot] = Tap(current->timestamp_, cur->x_pos_, cur->y_pos_);
} else if (tracked_taps_[slot].start_ > 0) {
// Check if this finger has moved too far to be considered a tap.
if (kMaxTapMovement2 < Distance2(cur->x_pos_, cur->y_pos_,
tracked_taps_[slot].x_pos_, tracked_taps_[slot].y_pos_))
tracked_taps_[slot].start_ = 0;
}
if (tracked_taps_[slot].start_ > 0) {
// Check distance from other tracked taps.
__s32 min_distance2 = -1;
for (size_t i = 0; i < num_slots; i++) {
if (i == slot || tracked_taps_[i].start_ == 0)
continue;
__s32 dist2 = Distance2(tracked_taps_[i].x_pos_,
tracked_taps_[i].y_pos_,
cur->x_pos_, cur->y_pos_);
if (min_distance2 < 0 || dist2 < min_distance2)
min_distance2 = dist2;
}
if (min_distance2 > kMinDistance2) {
// The other finger should see this one on its next frame and also
// get canceled.
Log("Cancel tracking id %d %.0fpx from other current taps.",
departing ? prev->tracking_id_ : cur->tracking_id_,
sqrt(min_distance2));
cur->canceled_ = true;
}
}
if (departing)
tracked_taps_[slot].start_ = 0;
}
}
} // namespace touch_noise_filter