xref: /aosp_15_r20/external/libchrome-gestures/include/util.h (revision aed3e5085e770be5b69ce25295ecf6ddf906af95)
1*aed3e508SAndroid Build Coastguard Worker // Copyright 2012 The ChromiumOS Authors
2*aed3e508SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*aed3e508SAndroid Build Coastguard Worker // found in the LICENSE file.
4*aed3e508SAndroid Build Coastguard Worker 
5*aed3e508SAndroid Build Coastguard Worker #ifndef GESTURES_UTIL_H_
6*aed3e508SAndroid Build Coastguard Worker #define GESTURES_UTIL_H_
7*aed3e508SAndroid Build Coastguard Worker 
8*aed3e508SAndroid Build Coastguard Worker #include <list>
9*aed3e508SAndroid Build Coastguard Worker #include <map>
10*aed3e508SAndroid Build Coastguard Worker #include <set>
11*aed3e508SAndroid Build Coastguard Worker #include <vector>
12*aed3e508SAndroid Build Coastguard Worker 
13*aed3e508SAndroid Build Coastguard Worker #include <math.h>
14*aed3e508SAndroid Build Coastguard Worker 
15*aed3e508SAndroid Build Coastguard Worker #include "include/gestures.h"
16*aed3e508SAndroid Build Coastguard Worker #include "include/interpreter.h"
17*aed3e508SAndroid Build Coastguard Worker 
18*aed3e508SAndroid Build Coastguard Worker namespace gestures {
19*aed3e508SAndroid Build Coastguard Worker 
FloatEq(float a,float b)20*aed3e508SAndroid Build Coastguard Worker inline bool FloatEq(float a, float b) {
21*aed3e508SAndroid Build Coastguard Worker   return fabsf(a - b) <= 1e-5;
22*aed3e508SAndroid Build Coastguard Worker }
23*aed3e508SAndroid Build Coastguard Worker 
DoubleEq(float a,float b)24*aed3e508SAndroid Build Coastguard Worker inline bool DoubleEq(float a, float b) {
25*aed3e508SAndroid Build Coastguard Worker   return fabsf(a - b) <= 1e-8;
26*aed3e508SAndroid Build Coastguard Worker }
27*aed3e508SAndroid Build Coastguard Worker 
28*aed3e508SAndroid Build Coastguard Worker // Returns the square of the distance between the two contacts.
29*aed3e508SAndroid Build Coastguard Worker template<typename ContactTypeA, typename ContactTypeB>
DistSq(const ContactTypeA & finger_a,const ContactTypeB & finger_b)30*aed3e508SAndroid Build Coastguard Worker float DistSq(const ContactTypeA& finger_a, const ContactTypeB& finger_b) {
31*aed3e508SAndroid Build Coastguard Worker   float dx = finger_a.position_x - finger_b.position_x;
32*aed3e508SAndroid Build Coastguard Worker   float dy = finger_a.position_y - finger_b.position_y;
33*aed3e508SAndroid Build Coastguard Worker   return dx * dx + dy * dy;
34*aed3e508SAndroid Build Coastguard Worker }
35*aed3e508SAndroid Build Coastguard Worker template<typename ContactType>  // UnmergedContact or FingerState
DistSqXY(const ContactType & finger_a,float pos_x,float pos_y)36*aed3e508SAndroid Build Coastguard Worker float DistSqXY(const ContactType& finger_a, float pos_x, float pos_y) {
37*aed3e508SAndroid Build Coastguard Worker   float dx = finger_a.position_x - pos_x;
38*aed3e508SAndroid Build Coastguard Worker   float dy = finger_a.position_y - pos_y;
39*aed3e508SAndroid Build Coastguard Worker   return dx * dx + dy * dy;
40*aed3e508SAndroid Build Coastguard Worker }
41*aed3e508SAndroid Build Coastguard Worker 
42*aed3e508SAndroid Build Coastguard Worker template<typename ContactType>
CompareX(const void * a_ptr,const void * b_ptr)43*aed3e508SAndroid Build Coastguard Worker int CompareX(const void* a_ptr, const void* b_ptr) {
44*aed3e508SAndroid Build Coastguard Worker   const ContactType* a = *static_cast<const ContactType* const*>(a_ptr);
45*aed3e508SAndroid Build Coastguard Worker   const ContactType* b = *static_cast<const ContactType* const*>(b_ptr);
46*aed3e508SAndroid Build Coastguard Worker   return a->position_x < b->position_x ? -1 : a->position_x > b->position_x;
47*aed3e508SAndroid Build Coastguard Worker }
48*aed3e508SAndroid Build Coastguard Worker 
49*aed3e508SAndroid Build Coastguard Worker template<typename ContactType>
CompareY(const void * a_ptr,const void * b_ptr)50*aed3e508SAndroid Build Coastguard Worker int CompareY(const void* a_ptr, const void* b_ptr) {
51*aed3e508SAndroid Build Coastguard Worker   const ContactType* a = *static_cast<const ContactType* const*>(a_ptr);
52*aed3e508SAndroid Build Coastguard Worker   const ContactType* b = *static_cast<const ContactType* const*>(b_ptr);
53*aed3e508SAndroid Build Coastguard Worker   return a->position_y < b->position_y ? -1 : a->position_y > b->position_y;
54*aed3e508SAndroid Build Coastguard Worker }
55*aed3e508SAndroid Build Coastguard Worker 
DegToRad(float degrees)56*aed3e508SAndroid Build Coastguard Worker inline float DegToRad(float degrees) {
57*aed3e508SAndroid Build Coastguard Worker   return M_PI * degrees / 180.0;
58*aed3e508SAndroid Build Coastguard Worker }
59*aed3e508SAndroid Build Coastguard Worker 
60*aed3e508SAndroid Build Coastguard Worker template<typename Map, typename Key> static inline
MapContainsKey(const Map & the_map,const Key & the_key)61*aed3e508SAndroid Build Coastguard Worker bool MapContainsKey(const Map& the_map, const Key& the_key) {
62*aed3e508SAndroid Build Coastguard Worker   return the_map.find(the_key) != the_map.end();
63*aed3e508SAndroid Build Coastguard Worker }
64*aed3e508SAndroid Build Coastguard Worker 
65*aed3e508SAndroid Build Coastguard Worker // Removes any ids from the map that are not finger ids in hs.
66*aed3e508SAndroid Build Coastguard Worker template<typename Data>
RemoveMissingIdsFromMap(std::map<short,Data> * the_map,const HardwareState & hs)67*aed3e508SAndroid Build Coastguard Worker void RemoveMissingIdsFromMap(std::map<short, Data>* the_map,
68*aed3e508SAndroid Build Coastguard Worker                              const HardwareState& hs) {
69*aed3e508SAndroid Build Coastguard Worker   std::map<short, Data> removed;
70*aed3e508SAndroid Build Coastguard Worker   for (const auto& [key, value] : *the_map) {
71*aed3e508SAndroid Build Coastguard Worker     if (!hs.GetFingerState(key))
72*aed3e508SAndroid Build Coastguard Worker       removed[key] = value;
73*aed3e508SAndroid Build Coastguard Worker   }
74*aed3e508SAndroid Build Coastguard Worker   for (const auto& [key, value] : removed)
75*aed3e508SAndroid Build Coastguard Worker     the_map->erase(key);
76*aed3e508SAndroid Build Coastguard Worker }
77*aed3e508SAndroid Build Coastguard Worker 
78*aed3e508SAndroid Build Coastguard Worker // Removes any ids from the set that are not finger ids in hs.
79*aed3e508SAndroid Build Coastguard Worker static inline
RemoveMissingIdsFromSet(std::set<short> * the_set,const HardwareState & hs)80*aed3e508SAndroid Build Coastguard Worker void RemoveMissingIdsFromSet(std::set<short>* the_set,
81*aed3e508SAndroid Build Coastguard Worker                              const HardwareState& hs) {
82*aed3e508SAndroid Build Coastguard Worker   std::vector<short> old_ids;
83*aed3e508SAndroid Build Coastguard Worker   old_ids.reserve(the_set->size() + 1);
84*aed3e508SAndroid Build Coastguard Worker   for (typename std::set<short>::const_iterator it = the_set->begin();
85*aed3e508SAndroid Build Coastguard Worker        it != the_set->end(); ++it)
86*aed3e508SAndroid Build Coastguard Worker     if (!hs.GetFingerState(*it))
87*aed3e508SAndroid Build Coastguard Worker       old_ids.push_back(*it);
88*aed3e508SAndroid Build Coastguard Worker   for (auto id : old_ids)
89*aed3e508SAndroid Build Coastguard Worker     the_set->erase(id);
90*aed3e508SAndroid Build Coastguard Worker }
91*aed3e508SAndroid Build Coastguard Worker 
92*aed3e508SAndroid Build Coastguard Worker template<typename Set, typename Elt>
SetContainsValue(const Set & the_set,const Elt & elt)93*aed3e508SAndroid Build Coastguard Worker inline bool SetContainsValue(const Set& the_set,
94*aed3e508SAndroid Build Coastguard Worker                              const Elt& elt) {
95*aed3e508SAndroid Build Coastguard Worker   return the_set.find(elt) != the_set.end();
96*aed3e508SAndroid Build Coastguard Worker }
97*aed3e508SAndroid Build Coastguard Worker 
98*aed3e508SAndroid Build Coastguard Worker template<typename Elem>
99*aed3e508SAndroid Build Coastguard Worker class List : public std::list<Elem> {
100*aed3e508SAndroid Build Coastguard Worker public:
at(int offset)101*aed3e508SAndroid Build Coastguard Worker   Elem& at(int offset) {
102*aed3e508SAndroid Build Coastguard Worker     // Traverse to the appropriate offset
103*aed3e508SAndroid Build Coastguard Worker     if (offset < 0) {
104*aed3e508SAndroid Build Coastguard Worker       // negative offset is from end to begin
105*aed3e508SAndroid Build Coastguard Worker       for (auto iter = this->rbegin(); iter != this->rend(); ++iter) {
106*aed3e508SAndroid Build Coastguard Worker         if (++offset == 0)
107*aed3e508SAndroid Build Coastguard Worker           return *iter;
108*aed3e508SAndroid Build Coastguard Worker       }
109*aed3e508SAndroid Build Coastguard Worker     } else {
110*aed3e508SAndroid Build Coastguard Worker       // positive offset is from begin to end
111*aed3e508SAndroid Build Coastguard Worker       for (auto iter = this->begin(); iter != this->end(); ++iter) {
112*aed3e508SAndroid Build Coastguard Worker         if (offset-- == 0)
113*aed3e508SAndroid Build Coastguard Worker           return *iter;
114*aed3e508SAndroid Build Coastguard Worker       }
115*aed3e508SAndroid Build Coastguard Worker     }
116*aed3e508SAndroid Build Coastguard Worker     // Invalid offset
117*aed3e508SAndroid Build Coastguard Worker     abort();
118*aed3e508SAndroid Build Coastguard Worker   }
119*aed3e508SAndroid Build Coastguard Worker };
120*aed3e508SAndroid Build Coastguard Worker 
121*aed3e508SAndroid Build Coastguard Worker }  // namespace gestures
122*aed3e508SAndroid Build Coastguard Worker 
123*aed3e508SAndroid Build Coastguard Worker #endif  // GESTURES_UTIL_H_
124