00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "pointerEventList.h"
00016 #include "indent.h"
00017 #include "config_event.h"
00018 #include "clockObject.h"
00019 #include "deg_2_rad.h"
00020 #include "cmath.h"
00021
00022 TypeHandle PointerEventList::_type_handle;
00023
00024
00025
00026
00027
00028
00029
00030 INLINE double delta_angle(double angle1, double angle2) {
00031 double deltang = angle2 - angle1;
00032 while (deltang < -180.0) deltang += 360.0;
00033 while (deltang > 180.0) deltang -= 360.0;
00034 return deltang;
00035 }
00036
00037
00038
00039
00040
00041
00042
00043
00044 INLINE double normalize_angle(double angle) {
00045 while (angle < 0.0) angle += 360.0;
00046 while (angle > 360.0) angle -= 360.0;
00047 return angle;
00048 }
00049
00050
00051
00052
00053
00054
00055
00056
00057 void PointerEventList::
00058 output(ostream &out) const {
00059 if (_events.empty()) {
00060 out << "(no pointers)";
00061 } else {
00062 Events::const_iterator ei;
00063 ei = _events.begin();
00064 out << "(" << (*ei);
00065 ++ei;
00066 while (ei != _events.end()) {
00067 out << " " << (*ei);
00068 ++ei;
00069 }
00070 out << ")";
00071 }
00072 }
00073
00074
00075
00076
00077
00078
00079 void PointerEventList::
00080 write(ostream &out, int indent_level) const {
00081 indent(out, indent_level) << _events.size() << " events:\n";
00082 Events::const_iterator ei;
00083 for (ei = _events.begin(); ei != _events.end(); ++ei) {
00084 indent(out, indent_level + 2) << (*ei) << "\n";
00085 }
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095 void PointerEventList::
00096 add_event(bool in_win, int xpos, int ypos, int seq, double time) {
00097 PointerEvent pe;
00098 pe._in_window = in_win;
00099 pe._xpos = xpos;
00100 pe._ypos = ypos;
00101 pe._sequence = seq;
00102 pe._time = time;
00103 if (_events.size() > 0) {
00104 pe._dx = xpos - _events.back()._xpos;
00105 pe._dy = ypos - _events.back()._ypos;
00106 double ddx = pe._dx;
00107 double ddy = pe._dy;
00108 pe._length = csqrt(ddx*ddx + ddy*ddy);
00109 if (pe._length > 0.0) {
00110 pe._direction = normalize_angle(rad_2_deg(catan2(-ddy,ddx)));
00111 } else {
00112 pe._direction = _events.back()._direction;
00113 }
00114 pe._rotation = delta_angle(_events.back()._direction, pe._direction);
00115 } else {
00116 pe._dx = 0;
00117 pe._dy = 0;
00118 pe._length = 0.0;
00119 pe._direction = 0.0;
00120 pe._rotation = 0.0;
00121 }
00122 _events.push_back(pe);
00123 }
00124
00125
00126
00127
00128
00129
00130
00131 bool PointerEventList::
00132 encircles(int x, int y) const {
00133 int tot_events = _events.size();
00134 if (tot_events < 3) {
00135 return false;
00136 }
00137 int last = tot_events-1;
00138 double dx = _events[last]._xpos - x;
00139 double dy = _events[last]._ypos - y;
00140 double lastang = rad_2_deg(catan2(dy, dx));
00141 double total = 0.0;
00142 for (int i=last; (i>=0) && (total < 360.0) && (total > -360.0); i--) {
00143 dx = _events[i]._xpos - x;
00144 dy = _events[i]._ypos - y;
00145 if ((dx==0.0)&&(dy==0.0)) {
00146 continue;
00147 }
00148 double angle = rad_2_deg(catan2(dy,dx));
00149 double deltang = delta_angle(lastang, angle);
00150 if (deltang * total < 0.0) {
00151 total = 0.0;
00152 }
00153 total += deltang;
00154 lastang = angle;
00155 }
00156 return (total > 360.0) || (total < -360.0);
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 double PointerEventList::
00169 total_turns(double sec) const {
00170 double old = ClockObject::get_global_clock()->get_frame_time() - sec;
00171 int pos = _events.size()-1;
00172 double tot = 0.0;
00173 while ((pos >= 0)&&(_events[pos]._time >= old)) {
00174 double rot = _events[pos]._rotation;
00175 if (rot < 0.0) rot = -rot;
00176 tot += rot;
00177 }
00178 return tot;
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 double PointerEventList::
00198 match_pattern(const string &ascpat, double rot, double seglen) {
00199
00200 vector_double pattern;
00201 parse_pattern(ascpat, pattern);
00202
00203
00204 for (size_t i=0; i<pattern.size(); i++) {
00205 pattern[i] = normalize_angle(pattern[i] + rot);
00206 }
00207
00208 return 0.0;
00209 }
00210
00211
00212
00213
00214
00215
00216 void PointerEventList::
00217 parse_pattern(const string &ascpat, vector_double &pattern) {
00218 int chars = 0;
00219 double dir = 180.0;
00220 for (size_t i=0; i<ascpat.size(); i++) {
00221 char c = ascpat[i];
00222 double ang = -1.0;
00223 if ((c=='E')||(c=='e')) ang=0.0;
00224 else if ((c=='N')||(c=='n')) ang=90.0;
00225 else if ((c=='W')||(c=='w')) ang=180.0;
00226 else if ((c=='S')||(c=='s')) ang=270.0;
00227 if (ang >= 0.0) {
00228 double offset = delta_angle(dir, ang);
00229 double newang = dir + offset;
00230 dir = normalize_angle((dir * chars + newang) / (chars + 1));
00231 chars += 1;
00232 } else {
00233 if ((c != ' ')&&(c != '\t')) {
00234 event_cat.warning() <<
00235 "Invalid pattern in PointerEventList::match_pattern\n";
00236 pattern.clear();
00237 return;
00238 }
00239 if (chars > 0) {
00240 pattern.push_back(dir);
00241 }
00242 chars = 0;
00243 dir = 180.0;
00244 }
00245 }
00246 if (chars > 0) {
00247 pattern.push_back(dir);
00248 }
00249
00250 cerr << "Pattern: ";
00251 for (int i=0; i<(int)pattern.size(); i++) {
00252 cerr << pattern[i] << " ";
00253 }
00254 cerr << "\n";
00255 }