xref: /aosp_15_r20/external/libchrome-gestures/include/finger_metrics.h (revision aed3e5085e770be5b69ce25295ecf6ddf906af95)
1 // Copyright 2012 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef GESTURES_FINGER_METRICS_H_
6 #define GESTURES_FINGER_METRICS_H_
7 
8 #include <cmath>
9 #include <vector>
10 
11 #include "include/gestures.h"
12 #include "include/prop_registry.h"
13 
14 namespace gestures {
15 
16 static const size_t kMaxFingers = 10;
17 static const size_t kMaxGesturingFingers = 4;
18 static const size_t kMaxTapFingers = 10;
19 
20 // A datastructure describing a 2D vector in the mathematical sense.
21 struct Vector2 {
Vector2Vector222   Vector2() : x(0), y(0) {}
Vector2Vector223   Vector2(float x, float y) : x(x), y(y) {}
Vector2Vector224   Vector2(const Vector2& other) : x(other.x), y(other.y) {}
Vector2Vector225   explicit Vector2(const FingerState& state) : x(state.position_x),
26                                                y(state.position_y) {}
27 
SubVector228   Vector2 Sub(const Vector2& other) {
29     return Vector2(x - other.x, y - other.y);
30   }
31 
AddVector232   Vector2 Add(const Vector2& other) {
33     return Vector2(x + other.x, y + other.y);
34   }
35 
MagSqVector236   float MagSq() const {
37     return x * x + y * y;
38   }
MagVector239   float Mag() const {
40     return sqrtf(MagSq());
41   }
42   bool operator==(const Vector2& that) const {
43     return x == that.x && y == that.y;
44   }
45   bool operator!=(const Vector2& that) const {
46     return !(*this == that);
47   }
48 
49   float x;
50   float y;
51 };
52 
53 extern Vector2 Add(const Vector2& left, const Vector2& right);
54 extern Vector2 Sub(const Vector2& left, const Vector2& right);
55 extern float Dot(const Vector2& left, const Vector2& right);
56 
57 class MetricsProperties {
58  public:
59   explicit MetricsProperties(PropRegistry* prop_reg);
60 
61   // Maximum distance [mm] two fingers may be separated and still be eligible
62   // for a two-finger gesture (e.g., scroll / tap / click). These define an
63   // ellipse with horizontal and vertical axes lengths (think: radii).
64   DoubleProperty two_finger_close_horizontal_distance_thresh;
65   DoubleProperty two_finger_close_vertical_distance_thresh;
66 };
67 
68 // This class describes a finger and derives additional metrics that
69 // are useful for gesture recognition.
70 // In contrast to a FingerState an instance of this class has the
71 // lifetime of the duration the finger touches the touchpad. This allows
72 // metrics to be derived from the history of a finger.
73 class FingerMetrics {
74  public:
75   FingerMetrics();
76   explicit FingerMetrics(short tracking_id);
77   FingerMetrics(short tracking_id, stime_t timestamp);
78   FingerMetrics(const FingerState& state, stime_t timestamp);
79 
80   // Update the finger metrics from a FingerState.
81   // gesture_start: true if fingers have been added or removed during this
82   //                sync.
83   void Update(const FingerState& state, stime_t timestamp,
84               bool gesture_start);
85 
tracking_id()86   short tracking_id() const { return tracking_id_; }
87 
88   // current position
position()89   Vector2 position() const { return position_; }
90 
91   // position delta between current and last frame
delta()92   Vector2 delta() const { return delta_; }
93 
94   // origin is the time and position where the finger first touched
origin_position()95   Vector2 origin_position() const { return origin_position_; }
origin_time()96   stime_t origin_time() const { return origin_time_; }
origin_delta()97   Vector2 origin_delta() const { return Sub(position_, origin_position_); }
98 
99   // start is the time and postion where the fingers were located
100   // when the last of all current fingers touched (i.e. the gesture started)
start_position()101   Vector2 start_position() const { return start_position_; }
start_time()102   stime_t start_time() const { return start_time_; }
start_delta()103   Vector2 start_delta() const { return Sub(position_, start_position_); }
104 
105   // instances with the same tracking id are considered equal.
106   bool operator==(const FingerMetrics& other) const {
107     return other.tracking_id() == tracking_id_;
108   }
109 
110  private:
111   short tracking_id_;
112   Vector2 position_;
113   Vector2 delta_;
114   Vector2 origin_position_;
115   Vector2 start_position_;
116   stime_t origin_time_;
117   stime_t start_time_;
118 };
119 
120 // The Metrics class is a container for FingerMetrics and additional
121 // metrics that are based on the interaction of multiple fingers.
122 // It is responsible for keeping the FingerMetrics instances updated
123 // with the latest FingerStates.
124 class Metrics {
125  public:
126   Metrics(MetricsProperties* properties);
127 
128   bool CloseEnoughToGesture(const Vector2& pos_a,
129                             const Vector2& pos_b) const;
130 
131   // A collection of FingerMetrics describing the current hardware state.
132   // The collection is sorted to yield the oldest finger first.
fingers()133   std::vector<FingerMetrics>& fingers() { return fingers_; }
134 
135   // Find a FingerMetrics instance by it's tracking id.
136   // Returns nullptr if not found.
GetFinger(short tracking_id)137   FingerMetrics* GetFinger(short tracking_id) {
138       return const_cast<FingerMetrics*>(
139           const_cast<const Metrics*>(this)->GetFinger(tracking_id));
140   }
141   const FingerMetrics* GetFinger(short tracking_id) const;
142 
143   FingerMetrics* GetFinger(const FingerState& state);
144   const FingerMetrics* GetFinger(const FingerState& state) const;
145 
146   // Update the collection of FingerMetrics using information from 'hwstate'.
147   void Update(const HardwareState& hwstate);
148 
149   // Clear all finger information
150   void Clear();
151 
152   // Set the origin timestamp for a particular finger for testing purposes.
153   // Prefer calling Update with a whole HardwareState instead.
154   // TODO(b/307933752): remove this method once its last usage (in
155   // TapToClickStateMachineTest::check_hwstates) is removed.
156   void SetFingerOriginTimestampForTesting(short tracking_id, stime_t time);
157 
158  private:
159   std::vector<FingerMetrics> fingers_;
160 
161   MetricsProperties* properties_;
162   std::unique_ptr<MetricsProperties> own_properties_;
163 };
164 
165 }  // namespace gestures
166 
167 #endif  // GESTURES_FINGER_METRICS_H_
168