40 #define MAXPATHSIZE 1024
42 #define DOLLARNPOINTS 64
43 #define DOLLARSIZE 256
47 #define PHI 0.618033989
67 SDL_FloatPoint centroid;
68 SDL_DollarPath dollarPath;
71 int numDollarTemplates;
72 SDL_DollarTemplate *dollarTemplate;
82 static void PrintPath(SDL_FloatPoint *
path)
87 printf(
" (%f,%f)",path[i].
x,path[i].
y);
104 return (touchId < 0);
109 unsigned long hash = 5381;
112 hash = ((hash<<5) + hash) + (
unsigned long)points[i].
x;
113 hash = ((hash<<5) + hash) + (
unsigned long)points[i].
y;
121 if (src ==
NULL)
return 0;
140 for (j = 0; j < touch->numDollarTemplates; j++) {
152 for (j = 0; j < touch->numDollarTemplates; j++) {
153 if (touch->dollarTemplate[i].hash == gestureId) {
165 SDL_DollarTemplate* dollarTemplate;
166 SDL_DollarTemplate *templ;
169 index = inTouch->numDollarTemplates;
171 (SDL_DollarTemplate *)
SDL_realloc(inTouch->dollarTemplate,
173 sizeof(SDL_DollarTemplate));
174 if (!dollarTemplate) {
177 inTouch->dollarTemplate = dollarTemplate;
179 templ = &inTouch->dollarTemplate[
index];
182 inTouch->numDollarTemplates++;
191 if (inTouch ==
NULL) {
210 SDL_GestureTouch *touch =
NULL;
211 if (src ==
NULL)
return 0;
216 if (touch ==
NULL)
return -1;
220 SDL_DollarTemplate templ;
255 dist += (float)(
SDL_sqrt((p.x-templ[i].x)*(p.x-templ[
i].x)+
256 (p.y-templ[i].y)*(p.y-templ[
i].y)));
271 float x1 = (float)(
PHI*ta + (1-
PHI)*tb);
273 float x2 = (float)((1-
PHI)*ta +
PHI*tb);
280 x1 = (float)(
PHI*ta + (1-
PHI)*tb);
287 x2 = (float)((1-
PHI)*ta +
PHI*tb);
307 SDL_FloatPoint centroid;
308 float xmin,xmax,ymin,ymax;
311 float length = path->length;
315 for (i=1;i < path->numPoints; i++) {
316 float dx = path->p[
i ].x - path->p[i-1].x;
317 float dy = path->p[
i ].y - path->p[i-1].y;
318 length += (float)(
SDL_sqrt(dx*dx+dy*dy));
326 centroid.x = 0;centroid.y = 0;
329 for (i = 1; i < path->numPoints; i++) {
330 float d = (float)(
SDL_sqrt((path->p[i-1].x-path->p[i].x)*(path->p[i-1].x-path->p[
i].x)+
331 (path->p[i-1].y-path->p[i].y)*(path->p[i-1].y-path->p[
i].y)));
333 while (dist + d > interval) {
334 points[numPoints].x = path->p[i-1].x +
335 ((interval-dist)/d)*(path->p[
i].x-path->p[i-1].x);
336 points[numPoints].y = path->p[i-1].y +
337 ((interval-dist)/d)*(path->p[
i].y-path->p[i-1].y);
338 centroid.x += points[numPoints].x;
339 centroid.y += points[numPoints].y;
354 centroid.x /= numPoints;
355 centroid.y /= numPoints;
364 ang = (float)(
SDL_atan2(centroid.y - points[0].y,
365 centroid.x - points[0].x));
367 for (i = 0; i<numPoints; i++) {
368 float px = points[
i].x;
369 float py = points[
i].y;
370 points[
i].x = (float)((px - centroid.x)*
SDL_cos(ang) -
371 (py - centroid.y)*
SDL_sin(ang) + centroid.x);
372 points[
i].y = (float)((px - centroid.x)*
SDL_sin(ang) +
373 (py - centroid.y)*
SDL_cos(ang) + centroid.y);
376 if (points[i].
x < xmin) xmin = points[
i].x;
377 if (points[i].
x > xmax) xmax = points[
i].x;
378 if (points[i].
y < ymin) ymin = points[
i].y;
379 if (points[i].
y > ymax) ymax = points[
i].y;
386 for (i=0; i<numPoints; i++) {
397 float bestDiff = 10000;
405 for (i = 0; i < touch->numDollarTemplates; i++) {
407 if (diff < bestDiff) {bestDiff = diff; *bestTempl =
i;}
416 sizeof(SDL_GestureTouch));
450 event.mgesture.touchId = touch->id;
451 event.mgesture.x = touch->centroid.x;
452 event.mgesture.y = touch->centroid.y;
453 event.mgesture.dTheta = dTheta;
454 event.mgesture.dDist = dDist;
455 event.mgesture.numFingers = touch->numDownFingers;
464 event.dgesture.touchId = touch->id;
465 event.mgesture.x = touch->centroid.x;
466 event.mgesture.y = touch->centroid.y;
467 event.dgesture.gestureId = gestureId;
468 event.dgesture.error =
error;
470 event.dgesture.numFingers = touch->numDownFingers + 1;
479 event.dgesture.touchId = touch->id;
480 event.dgesture.gestureId = gestureId;
491 float pathDx, pathDy;
492 SDL_FloatPoint lastP;
493 SDL_FloatPoint lastCentroid;
505 if (inTouch ==
NULL)
return;
507 x =
event->tfinger.x;
508 y =
event->tfinger.y;
512 inTouch->numDownFingers--;
515 if (inTouch->recording) {
542 unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
549 if (inTouch->numDownFingers > 0) {
550 inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
551 x)/inTouch->numDownFingers;
552 inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
553 y)/inTouch->numDownFingers;
557 float dx =
event->tfinger.dx;
558 float dy =
event->tfinger.dy;
560 SDL_DollarPath* path = &inTouch->dollarPath;
562 path->p[path->numPoints].x = inTouch->centroid.x;
563 path->p[path->numPoints].y = inTouch->centroid.y;
565 (path->p[path->numPoints].x-path->p[path->numPoints-1].x);
567 (path->p[path->numPoints].y-path->p[path->numPoints-1].y);
568 path->length += (float)
SDL_sqrt(pathDx*pathDx + pathDy*pathDy);
574 lastCentroid = inTouch->centroid;
576 inTouch->centroid.x += dx/inTouch->numDownFingers;
577 inTouch->centroid.y += dy/inTouch->numDownFingers;
579 if (inTouch->numDownFingers > 1) {
583 lv.x = lastP.x - lastCentroid.x;
584 lv.y = lastP.y - lastCentroid.y;
585 lDist = (float)
SDL_sqrt(lv.x*lv.x + lv.y*lv.y);
587 v.x = x - inTouch->centroid.x;
588 v.y = y - inTouch->centroid.y;
590 Dist = (float)
SDL_sqrt(v.x*v.x+v.y*v.y);
598 dtheta = (float)
SDL_atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
600 dDist = (Dist - lDist);
601 if (lDist == 0) {dDist = 0;dtheta = 0;}
629 inTouch->numDownFingers++;
630 inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+
631 x)/inTouch->numDownFingers;
632 inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
633 y)/inTouch->numDownFingers;
638 inTouch->dollarPath.length = 0;
639 inTouch->dollarPath.p[0].x =
x;
640 inTouch->dollarPath.p[0].y =
y;
641 inTouch->dollarPath.numPoints = 1;
DECLSPEC double SDLCALL SDL_cos(double x)
DECLSPEC int SDLCALL SDL_PushEvent(SDL_Event *event)
Add an event to the event queue.
static unsigned long SDL_HashDollar(SDL_FloatPoint *points)
GLfloat GLfloat GLfloat GLfloat h
DECLSPEC double SDLCALL SDL_fabs(double x)
#define SDL_RWwrite(ctx, ptr, size, n)
static int SDL_AddDollarGesture_one(SDL_GestureTouch *inTouch, SDL_FloatPoint *path)
static SDL_GestureTouch * SDL_GetGestureTouch(SDL_TouchID id)
int SDL_SendGestureMulti(SDL_GestureTouch *touch, float dTheta, float dDist)
int SDL_numGestureTouches
DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size)
#define SDL_RWread(ctx, ptr, size, n)
static int SDL_SendDollarRecord(SDL_GestureTouch *touch, SDL_GestureID gestureId)
return Display return Display Bool Bool int d
GLsizei const GLchar *const * path
static float bestDollarDifference(SDL_FloatPoint *points, SDL_FloatPoint *templ)
DECLSPEC double SDLCALL SDL_sin(double x)
DECLSPEC int SDLCALL SDL_RecordGesture(SDL_TouchID touchId)
Begin Recording a gesture on the specified touch, or all touches (-1)
void SDL_GestureProcessEvent(SDL_Event *event)
int SDL_GestureAddTouch(SDL_TouchID touchId)
DECLSPEC int SDLCALL SDL_SaveDollarTemplate(SDL_GestureID gestureId, SDL_RWops *src)
Save a currently loaded Dollar Gesture template.
static float dollarRecognize(const SDL_DollarPath *path, int *bestTempl, SDL_GestureTouch *touch)
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
SDL_GestureTouch * SDL_gestureTouch
static int dollarNormalize(const SDL_DollarPath *path, SDL_FloatPoint *points)
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
GLuint GLfloat GLfloat GLfloat x1
static int SDL_SendGestureDollar(SDL_GestureTouch *touch, SDL_GestureID gestureId, float error)
EGLSurface EGLint EGLint y
#define SDL_OutOfMemory()
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
static int SDL_AddDollarGesture(SDL_GestureTouch *inTouch, SDL_FloatPoint *path)
DECLSPEC int SDLCALL SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src)
Load Dollar Gesture templates from a file.
DECLSPEC double SDLCALL SDL_sqrt(double x)
GLint GLint GLint GLint GLint w
uint16_t Uint16
An unsigned 16-bit integer type.
static float dollarDifference(SDL_FloatPoint *points, SDL_FloatPoint *templ, float ang)
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
DECLSPEC double SDLCALL SDL_atan2(double x, double y)
DECLSPEC int SDLCALL SDL_SaveAllDollarTemplates(SDL_RWops *src)
Save all currently loaded Dollar Gesture templates.
static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops *src)
SDL_TouchFingerEvent tfinger