Skip to content
Barryblueice edited this page Dec 29, 2025 · 1 revision
  • DeadZone(触控死区):
#define TAP_DEADZONE 20
...
int dx = abs((int)rx - (int)origin_x[id]);
int dy = abs((int)ry - (int)origin_y[id]);

if (dx > TAP_DEADZONE && dy > TAP_DEADZONE) {
    current_state.fingers[id].x = origin_x[id];
    current_state.fingers[id].y = origin_y[id];
} else {
    current_state.fingers[id].x = fx;
    current_state.fingers[id].y = fy;
}

通过触控死区判定消除轻微抖动,避免手指刚接触时Windows误判为移动。 如果手指移动距离 > DeadZone Threshold,则返回原点坐标。


  • 一阶滤波(低通滤波):

一阶滤波公式:y_new = $\alpha$ * $x_\text{current}$ + (1 - $\alpha$) * $y_\text{last}$

其中:

  • $y_\text{new}$:滤波后的当前值
  • $x_\text{current}$:当前输入值
  • $y_\text{last}$:上一帧滤波值
  • $\alpha$:滤波系数(0~1),数值越大响应越快

代码实现:

float dynamic_alpha = (dist > 30.0f) ? 0.8f : 0.3f;
filtered_x[id] = (dynamic_alpha * (float)rx) + ((1.0f - dynamic_alpha) * filtered_x[id]);
filtered_y[id] = (dynamic_alpha * (float)ry) + ((1.0f - dynamic_alpha) * filtered_y[id]);

dynamic_alpha根据距离动态调整:

  • 当手指移动距离大(快速移动)时,α高→快速响应
  • 当手指移动距离小(微小抖动)时,α低→平滑处理

通过一阶滤波保证手指移动平滑、视觉体验好,同时避免触控板抖动导致鼠标抖动。


  • Jump Threshold(跳变抑制):
if (last_raw_x[id] != 0 && abs((int)rx - (int)last_raw_x[id]) > JUMP_THRESHOLD) {
    current_state.fingers[id].x = last_raw_x[id];
    current_state.fingers[id].y = last_raw_y[id];
}

如果连续两次读取坐标差值超过跳变抑制阈值,则丢弃当前值,保持上一帧坐标。防止触控数据瞬间可能由芯片噪声或I2C读取错误导致的异常跳变。增加系统鲁棒性,避免鼠标瞬移或手势异常。


  • Settling(抖动稳定期):
if (active_count > 0 && active_count > 4 && (now - first_touch_time > SETTLING_MS)) {
    continue; 
}

用first_touch_time记录初次触摸时间,在短时间内(SETTLING_MS)忽略不完整触控数据。 避免刚接触时触发误判多指触控,提高多指手势识别稳定性。


  • 按键锁定:
static uint8_t locked_button = 0;
static bool is_detecting_click = false;

if (physical_pressed) {
    if (!is_detecting_click) {
        is_detecting_click = true;
        locked_button = (raw_x > 1700) ? 0x02 : 0x01;
    }
    msg_out->button_mask = locked_button;
} else {
    is_detecting_click = false;
    locked_button = 0;
    msg_out->button_mask = 0;
}

实现物理按键单击锁定,锁定按钮状态直到手指抬起,避免短时间内反复触发。

Clone this wiki locally