示例#1
0
static float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_GestureTouch* touch)
{

    SDL_FloatPoint points[DOLLARNPOINTS];
    int i;
    float bestDiff = 10000;

    dollarNormalize(path,points);

    //PrintPath(points);
    *bestTempl = -1;
    for (i = 0; i < touch->numDollarTemplates; i++) {
        float diff = bestDollarDifference(points,touch->dollarTemplate[i].path);
        if (diff < bestDiff) {bestDiff = diff; *bestTempl = i;}
    }
    return bestDiff;
}
示例#2
0
void SDL_GestureProcessEvent(SDL_Event* event)
{
    float x,y;
    SDL_FloatPoint path[DOLLARNPOINTS];
    int index;
    int i;
    float pathDx, pathDy;
    SDL_FloatPoint lastP;
    SDL_FloatPoint lastCentroid;
    float lDist;
    float Dist;
    float dtheta;
    float dDist;

    if (event->type == SDL_FINGERMOTION ||
        event->type == SDL_FINGERDOWN ||
        event->type == SDL_FINGERUP) {
        SDL_GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId);

        /* Shouldn't be possible */
        if (inTouch == NULL) return;

        x = event->tfinger.x;
        y = event->tfinger.y;

        /* Finger Up */
        if (event->type == SDL_FINGERUP) {
            inTouch->numDownFingers--;

#ifdef ENABLE_DOLLAR
            if (inTouch->recording) {
                inTouch->recording = SDL_FALSE;
                dollarNormalize(&inTouch->dollarPath,path);
                /* PrintPath(path); */
                if (recordAll) {
                    index = SDL_AddDollarGesture(NULL,path);
                    for (i = 0; i < SDL_numGestureTouches; i++)
                        SDL_gestureTouch[i].recording = SDL_FALSE;
                }
                else {
                    index = SDL_AddDollarGesture(inTouch,path);
                }

                if (index >= 0) {
                    SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
                }
                else {
                    SDL_SendDollarRecord(inTouch,-1);
                }
            }
            else {
                int bestTempl;
                float error;
                error = dollarRecognize(&inTouch->dollarPath,
                                        &bestTempl,inTouch);
                if (bestTempl >= 0){
                    /* Send Event */
                    unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
                    SDL_SendGestureDollar(inTouch,gestureId,error);
                    /* printf ("%s\n",);("Dollar error: %f\n",error); */
                }
            }
#endif
            /* inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers]; */
            if (inTouch->numDownFingers > 0) {
                inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
                                       x)/inTouch->numDownFingers;
                inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
                                       y)/inTouch->numDownFingers;
            }
        }
        else if (event->type == SDL_FINGERMOTION) {
            float dx = event->tfinger.dx;
            float dy = event->tfinger.dy;
#ifdef ENABLE_DOLLAR
            SDL_DollarPath* path = &inTouch->dollarPath;
            if (path->numPoints < MAXPATHSIZE) {
                path->p[path->numPoints].x = inTouch->centroid.x;
                path->p[path->numPoints].y = inTouch->centroid.y;
                pathDx =
                    (path->p[path->numPoints].x-path->p[path->numPoints-1].x);
                pathDy =
                    (path->p[path->numPoints].y-path->p[path->numPoints-1].y);
                path->length += (float)SDL_sqrt(pathDx*pathDx + pathDy*pathDy);
                path->numPoints++;
            }
#endif
            lastP.x = x - dx;
            lastP.y = y - dy;
            lastCentroid = inTouch->centroid;

            inTouch->centroid.x += dx/inTouch->numDownFingers;
            inTouch->centroid.y += dy/inTouch->numDownFingers;
            /* printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y); */
            if (inTouch->numDownFingers > 1) {
                SDL_FloatPoint lv; /* Vector from centroid to last x,y position */
                SDL_FloatPoint v; /* Vector from centroid to current x,y position */
                /* lv = inTouch->gestureLast[j].cv; */
                lv.x = lastP.x - lastCentroid.x;
                lv.y = lastP.y - lastCentroid.y;
                lDist = (float)SDL_sqrt(lv.x*lv.x + lv.y*lv.y);
                /* printf("lDist = %f\n",lDist); */
                v.x = x - inTouch->centroid.x;
                v.y = y - inTouch->centroid.y;
                /* inTouch->gestureLast[j].cv = v; */
                Dist = (float)SDL_sqrt(v.x*v.x+v.y*v.y);
                /* SDL_cos(dTheta) = (v . lv)/(|v| * |lv|) */

                /* Normalize Vectors to simplify angle calculation */
                lv.x/=lDist;
                lv.y/=lDist;
                v.x/=Dist;
                v.y/=Dist;
                dtheta = (float)SDL_atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);

                dDist = (Dist - lDist);
                if (lDist == 0) {dDist = 0;dtheta = 0;} /* To avoid impossible values */

                /* inTouch->gestureLast[j].dDist = dDist;
                inTouch->gestureLast[j].dtheta = dtheta;

                printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
                gdtheta = gdtheta*.9 + dtheta*.1;
                gdDist  =  gdDist*.9 +  dDist*.1
                knob.r += dDist/numDownFingers;
                knob.ang += dtheta;
                printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
                printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist); */
                SDL_SendGestureMulti(inTouch,dtheta,dDist);
            }
            else {
                /* inTouch->gestureLast[j].dDist = 0;
                inTouch->gestureLast[j].dtheta = 0;
                inTouch->gestureLast[j].cv.x = 0;
                inTouch->gestureLast[j].cv.y = 0; */
            }
            /* inTouch->gestureLast[j].f.p.x = x;
            inTouch->gestureLast[j].f.p.y = y;
            break;
            pressure? */
        }

        if (event->type == SDL_FINGERDOWN) {

            inTouch->numDownFingers++;
            inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+
                                   x)/inTouch->numDownFingers;
            inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
                                   y)/inTouch->numDownFingers;
            /* printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
                 inTouch->centroid.x,inTouch->centroid.y); */

#ifdef ENABLE_DOLLAR
            inTouch->dollarPath.length = 0;
            inTouch->dollarPath.p[0].x = x;
            inTouch->dollarPath.p[0].y = y;
            inTouch->dollarPath.numPoints = 1;
#endif
        }
    }
}