Bläddra i källkod

Working on a pattern matching routine.

Josh Yelon 18 år sedan
förälder
incheckning
e20aebfcaa
2 ändrade filer med 110 tillägg och 8 borttagningar
  1. 108 8
      panda/src/event/pointerEventList.cxx
  2. 2 0
      panda/src/event/pointerEventList.h

+ 108 - 8
panda/src/event/pointerEventList.cxx

@@ -18,12 +18,41 @@
 
 
 #include "pointerEventList.h"
 #include "pointerEventList.h"
 #include "indent.h"
 #include "indent.h"
+#include "config_event.h"
 #include "clockObject.h"
 #include "clockObject.h"
 #include "mathNumbers.h"
 #include "mathNumbers.h"
 #include <math.h>
 #include <math.h>
 
 
 TypeHandle PointerEventList::_type_handle;
 TypeHandle PointerEventList::_type_handle;
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: delta_angle
+//       Access: Static, Inline
+//  Description: Compute the difference between two angles.
+//               Returns a value in the range -180 to 180.
+////////////////////////////////////////////////////////////////////
+INLINE double delta_angle(double angle1, double angle2) {
+  double deltang = angle2 - angle1;
+  while (deltang < -180.0) deltang += 360.0;
+  while (deltang >  180.0) deltang -= 360.0;
+  return deltang;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: delta_angle
+//       Access: Static, Inline
+//  Description: Compute the difference between two angles.
+//               Returns a value in the range -180 to 180.
+////////////////////////////////////////////////////////////////////
+INLINE double normalize_angle(double angle) {
+  while (angle <   0.0) angle += 360.0;
+  while (angle > 360.0) angle -= 360.0;
+  return angle;
+}
+
+
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PointerEventList::output
 //     Function: PointerEventList::output
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -82,14 +111,11 @@ add_event(bool in_win, int xpos, int ypos, int seq, double time) {
     double ddy = pe._dy;
     double ddy = pe._dy;
     pe._length = sqrt(ddx*ddx + ddy*ddy);
     pe._length = sqrt(ddx*ddx + ddy*ddy);
     if (pe._length > 0.0) {
     if (pe._length > 0.0) {
-      pe._direction = atan2(-ddy,ddx) * (180.0 / MathNumbers::pi);
-      if (pe._direction < 0.0) pe._direction += 360.0;
+      pe._direction = normalize_angle(atan2(-ddy,ddx) * (180.0 / MathNumbers::pi));
     } else {
     } else {
       pe._direction = _events.back()._direction;
       pe._direction = _events.back()._direction;
     }
     }
-    pe._rotation = pe._direction - _events.back()._direction;
-    if (pe._rotation >  180.0) pe._rotation -= 360.0;
-    if (pe._rotation < -180.0) pe._rotation += 360.0;
+    pe._rotation = delta_angle(_events.back()._direction, pe._direction);
   } else {
   } else {
     pe._dx = 0;
     pe._dx = 0;
     pe._dy = 0;
     pe._dy = 0;
@@ -123,9 +149,7 @@ encircles(int x, int y) const {
       continue;
       continue;
     }
     }
     double angle = atan2(dy,dx) * (180.0/MathNumbers::pi);
     double angle = atan2(dy,dx) * (180.0/MathNumbers::pi);
-    double deltang = angle - lastang;
-    if (deltang < -180.0) deltang += 360.0;
-    if (deltang >  180.0) deltang -= 360.0;
+    double deltang = delta_angle(lastang, angle);
     if (deltang * total < 0.0) {
     if (deltang * total < 0.0) {
       total = 0.0;
       total = 0.0;
     }
     }
@@ -156,3 +180,79 @@ total_turns(double sec) const {
   }
   }
   return tot;
   return tot;
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerEventList::match_pattern
+//       Access: Published
+//  Description: This function is not implemented yet.  It is a work
+//               in progress.  The intent is as follows:
+//
+//               Returns a nonzero value if the mouse movements 
+//               match the specified pattern.  The higher the value,
+//               the better the match.  The pattern is a sequence
+//               of compass directions (ie, "E", "NE", etc) separated
+//               by spaces.  If rot is nonzero, then the pattern is
+//               rotated counterclockwise by the specified amount 
+//               before testing.  Seglen is the minimum length a
+//               mouse movement needs to be in order to be considered
+//               significant.
+////////////////////////////////////////////////////////////////////
+double PointerEventList::
+match_pattern(const string &ascpat, double rot, double seglen) {
+  // Convert the pattern from ascii to a more usable form.
+  pvector <double> pattern;
+  parse_pattern(ascpat, pattern);
+  
+  // Apply the rotation to the pattern.
+  for (size_t i=0; i<pattern.size(); i++) {
+    pattern[i] = normalize_angle(pattern[i] + rot);
+  }
+  
+  return 0.0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerEventList::parse_pattern
+//       Access: Private
+//  Description: Parses a pattern as used by match_pattern.
+////////////////////////////////////////////////////////////////////
+void PointerEventList::
+parse_pattern(const string &ascpat, pvector <double> &pattern) {
+  int chars = 0;
+  double dir = 180.0;
+  for (size_t i=0; i<ascpat.size(); i++) {
+    char c = ascpat[i];
+    double ang = -1.0;
+    if      ((c=='E')||(c=='e')) ang=0.0;
+    else if ((c=='N')||(c=='n')) ang=90.0;
+    else if ((c=='W')||(c=='w')) ang=180.0;
+    else if ((c=='S')||(c=='s')) ang=270.0;
+    if (ang >= 0.0) {
+      double offset = delta_angle(dir, ang);
+      double newang = dir + offset;
+      dir = normalize_angle((dir * chars + newang) / (chars + 1));
+      chars += 1;
+    } else {
+      if ((c != ' ')&&(c != '\t')) {
+        event_cat.warning() <<
+          "Invalid pattern in PointerEventList::match_pattern\n";
+        pattern.clear();
+        return;
+      }
+      if (chars > 0) {
+        pattern.push_back(dir);
+      }
+      chars = 0;
+      dir = 180.0;
+    }
+  }
+  if (chars > 0) {
+    pattern.push_back(dir);
+  }
+  
+  cerr << "Pattern: ";
+  for (int i=0; i<(int)pattern.size(); i++) {
+    cerr << pattern[i] << " ";
+  }
+  cerr << "\n";
+}

+ 2 - 0
panda/src/event/pointerEventList.h

@@ -60,6 +60,7 @@ PUBLISHED:
   
   
   bool   encircles(int x, int y) const;
   bool   encircles(int x, int y) const;
   double total_turns(double sec) const;
   double total_turns(double sec) const;
+  double match_pattern(const string &pattern, double rot, double seglen);
   
   
 public:
 public:
   INLINE PointerEventList(const PointerEventList &copy);
   INLINE PointerEventList(const PointerEventList &copy);
@@ -70,6 +71,7 @@ public:
   void write(ostream &out, int indent_level = 0) const;
   void write(ostream &out, int indent_level = 0) const;
 
 
 private:
 private:
+  void parse_pattern(const string &ascpat, pvector <double> &pattern);
   typedef pdeque<PointerEvent> Events;
   typedef pdeque<PointerEvent> Events;
   Events _events;
   Events _events;