Mercurial > sdl-ios-xcode
comparison touchTest/gestureTest.c @ 4656:b5007b7995c6
Added multi-finger gestures
author | Jim Grandpre <jim.tla@gmail.com> |
---|---|
date | Tue, 06 Jul 2010 02:05:27 -0700 |
parents | 4c94f2023d62 |
children |
comparison
equal
deleted
inserted
replaced
4655:4c94f2023d62 | 4656:b5007b7995c6 |
---|---|
38 Point p; | 38 Point p; |
39 float pressure; | 39 float pressure; |
40 int id; | 40 int id; |
41 } Finger; | 41 } Finger; |
42 | 42 |
43 typedef struct { | |
44 Finger f; | |
45 Point cv; | |
46 float dtheta,dDist; | |
47 } TouchPoint; | |
48 | |
43 typedef struct { //dt + s | 49 typedef struct { //dt + s |
44 Point d,s; //direction, start | 50 Point d,s; //direction, start |
45 int points; | 51 int points; |
46 } Line; | 52 } Line; |
47 | 53 |
51 | 57 |
52 int numPoints; | 58 int numPoints; |
53 Point p[EVENT_BUF_SIZE]; //To be safe | 59 Point p[EVENT_BUF_SIZE]; //To be safe |
54 } DollarPath; | 60 } DollarPath; |
55 | 61 |
62 typedef struct { | |
63 float ang,r; | |
64 Point p; | |
65 } Knob; | |
66 | |
67 Knob knob; | |
56 | 68 |
57 Finger finger[MAXFINGERS]; | 69 Finger finger[MAXFINGERS]; |
58 | 70 |
59 Finger gestureLast[MAXFINGERS]; | 71 |
60 DollarPath dollarPath[MAXFINGERS]; | 72 DollarPath dollarPath[MAXFINGERS]; |
61 | 73 |
62 #define MAXTEMPLATES 4 | 74 #define MAXTEMPLATES 4 |
63 | 75 |
64 Point dollarTemplate[MAXTEMPLATES][DOLLARNPOINTS]; | 76 Point dollarTemplate[MAXTEMPLATES][DOLLARNPOINTS]; |
117 void drawCircle(SDL_Surface* screen,int x,int y,int r,unsigned int c) | 129 void drawCircle(SDL_Surface* screen,int x,int y,int r,unsigned int c) |
118 { | 130 { |
119 | 131 |
120 float a; | 132 float a; |
121 int tx; | 133 int tx; |
122 /* | 134 |
123 for(a=0;a<PI/2;a+=1.f/(float)abs(r)) | |
124 { | |
125 if(r > 0) { //r > 0 ==> filled circle | |
126 for(tx=x-r*cos(a);tx<x+r*cos(a);tx++) { | |
127 setpix(screen,tx,(int)(y+r*sin(a)),c); | |
128 setpix(screen,tx,(int)(y-r*sin(a)),c); | |
129 } | |
130 } else { | |
131 //Draw Outline | |
132 setpix(screen,(int)(x+r*cos(a)),(int)(y+r*sin(a)),c); | |
133 setpix(screen,(int)(x-r*cos(a)),(int)(y+r*sin(a)),c); | |
134 setpix(screen,(int)(x+r*cos(a)),(int)(y-r*sin(a)),c); | |
135 setpix(screen,(int)(x-r*cos(a)),(int)(y-r*sin(a)),c); | |
136 } | |
137 }*/ | |
138 int ty; | 135 int ty; |
139 float xr; | 136 float xr; |
140 for(ty = -abs(r);ty <= abs(r);ty++) { | 137 for(ty = -abs(r);ty <= abs(r);ty++) { |
141 xr = sqrt(r*r - ty*ty); | 138 xr = sqrt(r*r - ty*ty); |
142 if(r > 0) { //r > 0 ==> filled circle | 139 if(r > 0) { //r > 0 ==> filled circle |
147 else { | 144 else { |
148 setpix(screen,x-xr+.5,y+ty,c); | 145 setpix(screen,x-xr+.5,y+ty,c); |
149 setpix(screen,x+xr-.5,y+ty,c); | 146 setpix(screen,x+xr-.5,y+ty,c); |
150 } | 147 } |
151 } | 148 } |
149 } | |
150 | |
151 void drawKnob(SDL_Surface* screen,Knob k) { | |
152 printf("Knob: x = %f, y = %f, r = %f, a = %f\n",k.p.x,k.p.y,k.r,k.ang); | |
153 | |
154 drawCircle(screen,k.p.x*screen->w,k.p.y*screen->h,k.r*screen->w,0xFFFFFF); | |
155 | |
156 drawCircle(screen,(k.p.x+k.r/2*cos(k.ang))*screen->w, | |
157 (k.p.y+k.r/2*sin(k.ang))*screen->h,k.r/4*screen->w,0); | |
158 | |
152 } | 159 } |
153 | 160 |
154 void drawDollarPath(SDL_Surface* screen,Point* points,int numPoints, | 161 void drawDollarPath(SDL_Surface* screen,Point* points,int numPoints, |
155 int rad,unsigned int col){ | 162 int rad,unsigned int col){ |
156 int i; | 163 int i; |
201 f1 = f2; | 208 f1 = f2; |
202 x2 = (1-PHI)*ta + PHI*tb; | 209 x2 = (1-PHI)*ta + PHI*tb; |
203 f2 = dollarDifference(points,templ,x2); | 210 f2 = dollarDifference(points,templ,x2); |
204 } | 211 } |
205 } | 212 } |
206 return SDL_min(f1,f2); | 213 /* |
207 | 214 if(f1 <= f2) |
215 printf("Min angle (x1): %f\n",x1); | |
216 else if(f1 > f2) | |
217 printf("Min angle (x2): %f\n",x2); | |
218 */ | |
219 return SDL_min(f1,f2); | |
208 } | 220 } |
209 | 221 |
210 float dollarRecognize(SDL_Surface* screen, DollarPath path,int *bestTempl) { | 222 float dollarRecognize(SDL_Surface* screen, DollarPath path,int *bestTempl) { |
211 | 223 |
212 Point points[DOLLARNPOINTS]; | 224 Point points[DOLLARNPOINTS]; |
331 //setpix(screen,x,y,0); //Inefficient, but that's okay... | 343 //setpix(screen,x,y,0); //Inefficient, but that's okay... |
332 } | 344 } |
333 } | 345 } |
334 drawCircle(screen,mousx,mousy,-30,0xFFFFFF); | 346 drawCircle(screen,mousx,mousy,-30,0xFFFFFF); |
335 drawLine(screen,0,0,screen->w,screen->h,0xFFFFFF); | 347 drawLine(screen,0,0,screen->w,screen->h,0xFFFFFF); |
348 | |
336 int i; | 349 int i; |
337 //draw Touch History | 350 //draw Touch History |
351 TouchPoint gestureLast[MAXFINGERS]; | |
352 //printf("------------------Start History------------------\n"); | |
338 for(i = 0;i < MAXFINGERS;i++) { | 353 for(i = 0;i < MAXFINGERS;i++) { |
339 gestureLast[i].id = -1; | 354 gestureLast[i].f.id = -1; |
340 #ifdef DRAW_VECTOR_EST | 355 } |
341 gestureLine[i].points = 0; | 356 int numDownFingers = 0; |
342 #endif | 357 Point centroid; |
343 } | 358 float gdtheta,gdDist; |
344 for(i = SDL_max(0,eventWrite - EVENT_BUF_SIZE);i != eventWrite;i++) { | 359 |
360 | |
361 for(i = SDL_max(0,eventWrite - EVENT_BUF_SIZE);i < eventWrite;i++) { | |
345 SDL_Event event = events[i&(EVENT_BUF_SIZE-1)]; | 362 SDL_Event event = events[i&(EVENT_BUF_SIZE-1)]; |
346 int age = eventWrite - i - 1; | 363 int age = eventWrite - i - 1; |
347 if(event.type == SDL_FINGERMOTION || | 364 if(event.type == SDL_FINGERMOTION || |
348 event.type == SDL_FINGERDOWN || | 365 event.type == SDL_FINGERDOWN || |
349 event.type == SDL_FINGERUP) { | 366 event.type == SDL_FINGERUP) { |
353 float x = ((float)event.tfinger.x)/inTouch->xres; | 370 float x = ((float)event.tfinger.x)/inTouch->xres; |
354 float y = ((float)event.tfinger.y)/inTouch->yres; | 371 float y = ((float)event.tfinger.y)/inTouch->yres; |
355 int j,empty = -1; | 372 int j,empty = -1; |
356 | 373 |
357 for(j = 0;j<MAXFINGERS;j++) { | 374 for(j = 0;j<MAXFINGERS;j++) { |
358 if(gestureLast[j].id == event.tfinger.fingerId) { | 375 if(gestureLast[j].f.id == event.tfinger.fingerId) { |
359 if(event.type == SDL_FINGERUP) { | 376 if(event.type == SDL_FINGERUP) { |
360 #ifdef DRAW_VECTOR_EST | 377 numDownFingers--; |
361 if(gestureLine[j].points > 0) | 378 if(numDownFingers <= 1) { |
362 drawLine(screen, | 379 gdtheta = 0; |
363 gestureLine[j].s.x*screen->w, | 380 gdDist = 0; |
364 gestureLine[j].s.y*screen->h, | 381 } |
365 (gestureLine[j].s.x +50*gestureLine[j].d.x)*screen->w, | |
366 (gestureLine[j].s.y +50*gestureLine[j].d.y)*screen->h, | |
367 0xFF00); | |
368 | |
369 gestureLine[j].points = 0; | |
370 #endif | |
371 | |
372 if(!keystat[32]){ //spacebar | 382 if(!keystat[32]){ //spacebar |
373 int bestTempl; | 383 int bestTempl; |
374 float error = dollarRecognize(screen,dollarPath[j],&bestTempl); | 384 float error = dollarRecognize(screen,dollarPath[j],&bestTempl); |
375 if(bestTempl >= 0){ | 385 if(bestTempl >= 0){ |
376 drawDollarPath(screen,dollarTemplate[bestTempl] | 386 drawDollarPath(screen,dollarTemplate[bestTempl] |
377 ,DOLLARNPOINTS,-15,0x0066FF); | 387 ,DOLLARNPOINTS,-15,0x0066FF); |
378 | 388 printf("Dollar error: %f\n",error); |
379 printf("ERROR: %f\n",error); | |
380 } | 389 } |
381 | 390 |
382 } | 391 } |
383 else if(numDollarTemplates < MAXTEMPLATES) { | 392 else if(numDollarTemplates < MAXTEMPLATES) { |
384 | 393 |
385 dollarNormalize(dollarPath[j], | 394 dollarNormalize(dollarPath[j], |
386 dollarTemplate[numDollarTemplates]); | 395 dollarTemplate[numDollarTemplates]); |
387 int k; | |
388 /* | 396 /* |
397 int k; | |
389 for(k = 0;k<DOLLARNPOINTS;k++) { | 398 for(k = 0;k<DOLLARNPOINTS;k++) { |
390 printf("(%f,%f)\n",dollarTemplate[numDollarTemplates][i].x, | 399 printf("(%f,%f)\n",dollarTemplate[numDollarTemplates][i].x, |
391 dollarTemplate[numDollarTemplates][i].y); | 400 dollarTemplate[numDollarTemplates][i].y); |
392 }*/ | 401 }*/ |
393 numDollarTemplates++; | 402 numDollarTemplates++; |
394 } | 403 } |
395 | 404 |
396 gestureLast[j].id = -1; | 405 gestureLast[j].f.id = -1; |
397 break; | 406 break; |
398 } | 407 } |
399 else { | 408 else { |
400 #ifdef DRAW_VECTOR_EST | |
401 if(gestureLine[j].points == 1) { | |
402 gestureLine[j].d.x = x - gestureLine[j].s.x; | |
403 gestureLine[j].d.y = y - gestureLine[j].s.y; | |
404 } | |
405 | |
406 gestureLine[j].s.x = gestureLine[j].s.x*gestureLine[j].points+x; | |
407 gestureLine[j].s.y = gestureLine[j].s.y*gestureLine[j].points+y; | |
408 | |
409 gestureLine[j].d.x = gestureLine[j].d.x*gestureLine[j].points+ | |
410 x - gestureLast[j].p.x; | |
411 gestureLine[j].d.y = gestureLine[j].d.y*gestureLine[j].points+ | |
412 y - gestureLast[j].p.y;; | |
413 | |
414 | |
415 gestureLine[j].points++; | |
416 | |
417 gestureLine[j].s.x /= gestureLine[j].points; | |
418 gestureLine[j].s.y /= gestureLine[j].points; | |
419 | |
420 gestureLine[j].d.x /= gestureLine[j].points; | |
421 gestureLine[j].d.y /= gestureLine[j].points; | |
422 #endif | |
423 | |
424 dollarPath[j].p[dollarPath[j].numPoints].x = x; | 409 dollarPath[j].p[dollarPath[j].numPoints].x = x; |
425 dollarPath[j].p[dollarPath[j].numPoints].y = y; | 410 dollarPath[j].p[dollarPath[j].numPoints].y = y; |
426 float dx = (dollarPath[j].p[dollarPath[j].numPoints-1].x- | 411 float dx = (dollarPath[j].p[dollarPath[j].numPoints ].x- |
427 dollarPath[j].p[dollarPath[j].numPoints ].x); | 412 dollarPath[j].p[dollarPath[j].numPoints-1].x); |
428 float dy = (dollarPath[j].p[dollarPath[j].numPoints-1].y- | 413 float dy = (dollarPath[j].p[dollarPath[j].numPoints ].y- |
429 dollarPath[j].p[dollarPath[j].numPoints ].y); | 414 dollarPath[j].p[dollarPath[j].numPoints-1].y); |
430 dollarPath[j].length += sqrt(dx*dx + dy*dy); | 415 dollarPath[j].length += sqrt(dx*dx + dy*dy); |
431 | 416 |
432 dollarPath[j].numPoints++; | 417 dollarPath[j].numPoints++; |
433 | 418 |
434 | 419 centroid.x = centroid.x + dx/numDownFingers; |
435 gestureLast[j].p.x = x; | 420 centroid.y = centroid.y + dy/numDownFingers; |
436 gestureLast[j].p.y = y; | 421 if(numDownFingers > 1) { |
422 Point lv; //Vector from centroid to last x,y position | |
423 Point v; //Vector from centroid to current x,y position | |
424 lv.x = gestureLast[j].cv.x; | |
425 lv.y = gestureLast[j].cv.y; | |
426 float lDist = sqrt(lv.x*lv.x + lv.y*lv.y); | |
427 | |
428 v.x = x - centroid.x; | |
429 v.y = y - centroid.y; | |
430 gestureLast[j].cv = v; | |
431 float Dist = sqrt(v.x*v.x+v.y*v.y); | |
432 // cos(dTheta) = (v . lv)/(|v| * |lv|) | |
433 | |
434 lv.x/=lDist; | |
435 lv.y/=lDist; | |
436 v.x/=Dist; | |
437 v.y/=Dist; | |
438 float dtheta = atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y); | |
439 | |
440 float dDist = (lDist - Dist); | |
441 | |
442 gestureLast[j].dDist = dDist; | |
443 gestureLast[j].dtheta = dtheta; | |
444 | |
445 //gdtheta = gdtheta*.9 + dtheta*.1; | |
446 //gdDist = gdDist*.9 + dDist*.1 | |
447 gdtheta += dtheta; | |
448 gdDist += dDist; | |
449 | |
450 //printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist); | |
451 //printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist); | |
452 } | |
453 else { | |
454 gestureLast[j].dDist = 0; | |
455 gestureLast[j].dtheta = 0; | |
456 gestureLast[j].cv.x = 0; | |
457 gestureLast[j].cv.y = 0; | |
458 } | |
459 gestureLast[j].f.p.x = x; | |
460 gestureLast[j].f.p.y = y; | |
437 break; | 461 break; |
438 //pressure? | 462 //pressure? |
439 } | 463 } |
440 } | 464 } |
441 else if(gestureLast[j].id == -1 && empty == -1) { | 465 else if(gestureLast[j].f.id == -1 && empty == -1) { |
442 empty = j; | 466 empty = j; |
443 } | 467 } |
444 } | 468 } |
445 | 469 |
446 if(j >= MAXFINGERS && empty >= 0) { | 470 if(j >= MAXFINGERS && empty >= 0) { |
447 // printf("Finger Down!!!\n"); | 471 // printf("Finger Down!!!\n"); |
448 j = empty; //important that j is the index of the added finger | 472 numDownFingers++; |
449 gestureLast[j].id = event.tfinger.fingerId; | 473 centroid.x = (centroid.x*(numDownFingers - 1) + x)/numDownFingers; |
450 gestureLast[j].p.x = x; | 474 centroid.y = (centroid.y*(numDownFingers - 1) + y)/numDownFingers; |
451 gestureLast[j].p.y = y; | 475 |
452 #ifdef DRAW_VECTOR_EST | 476 j = empty; |
453 gestureLine[j].s.x = x; | 477 gestureLast[j].f.id = event.tfinger.fingerId; |
454 gestureLine[j].s.y = y; | 478 gestureLast[j].f.p.x = x; |
455 gestureLine[j].points = 1; | 479 gestureLast[j].f.p.y = y; |
456 #endif | 480 |
457 | 481 |
458 dollarPath[j].length = 0; | 482 dollarPath[j].length = 0; |
459 dollarPath[j].p[0].x = x; | 483 dollarPath[j].p[0].x = x; |
460 dollarPath[j].p[0].y = y; | 484 dollarPath[j].p[0].y = y; |
461 dollarPath[j].numPoints = 1; | 485 dollarPath[j].numPoints = 1; |
462 } | 486 } |
463 | 487 |
464 //draw the touch && each centroid: | 488 //draw the touch: |
465 | 489 |
466 if(gestureLast[j].id < 0) continue; //Finger up. Or some error... | 490 if(gestureLast[j].f.id < 0) continue; //Finger up. Or some error... |
467 int k; | 491 |
468 for(k = 0; k < MAXFINGERS;k++) { | 492 unsigned int c = colors[gestureLast[j].f.id%7]; |
469 if(gestureLast[k].id < 0) continue; | 493 unsigned int col = |
470 //printf("k = %i, id: %i\n",k,gestureLast[k].id); | 494 ((unsigned int)(c*(.1+.85))) | |
471 //colors have no alpha, so shouldn't overflow | 495 ((unsigned int)((0xFF*(1-((float)age)/EVENT_BUF_SIZE))) & 0xFF)<<24; |
472 unsigned int c = (colors[gestureLast[j].id%7] + | 496 x = gestureLast[j].f.p.x; |
473 colors[gestureLast[k].id%7])/2; | 497 y = gestureLast[j].f.p.y; |
498 if(event.type == SDL_FINGERMOTION) | |
499 drawCircle(screen,x*screen->w,y*screen->h,5,col); | |
500 else if(event.type == SDL_FINGERDOWN) | |
501 drawCircle(screen,x*screen->w,y*screen->h,-10,col); | |
502 | |
503 //if there is a centroid, draw it | |
504 if(numDownFingers > 1) { | |
474 unsigned int col = | 505 unsigned int col = |
475 ((unsigned int)(c*(.1+.85))) | | 506 ((unsigned int)(0xFFFFFF)) | |
476 ((unsigned int)((0xFF*(1-((float)age)/EVENT_BUF_SIZE))) & 0xFF)<<24; | 507 ((unsigned int)((0xFF*(1-((float)age)/EVENT_BUF_SIZE))) & 0xFF)<<24; |
477 x = (gestureLast[j].p.x + gestureLast[k].p.x)/2; | 508 drawCircle(screen,centroid.x*screen->w,centroid.y*screen->h,5,col); |
478 y = (gestureLast[j].p.y + gestureLast[k].p.y)/2; | 509 } |
479 if(event.type == SDL_FINGERMOTION) | |
480 drawCircle(screen,x*screen->w,y*screen->h,5,col); | |
481 else if(event.type == SDL_FINGERDOWN) | |
482 drawCircle(screen,x*screen->w,y*screen->h,-10,col); | |
483 } | |
484 } | 510 } |
485 } | 511 } |
486 | 512 |
487 | 513 |
488 for(i=0;i<MAXFINGERS;i++) | 514 for(i=0;i<MAXFINGERS;i++) |
492 ,20,0xFF*finger[i].pressure); | 518 ,20,0xFF*finger[i].pressure); |
493 else | 519 else |
494 drawCircle(screen,finger[i].p.x*screen->w,finger[i].p.y*screen->h | 520 drawCircle(screen,finger[i].p.x*screen->w,finger[i].p.y*screen->h |
495 ,20,0xFF); | 521 ,20,0xFF); |
496 | 522 |
497 | 523 |
498 keystat[32] = 0; | 524 |
499 | 525 keystat[32] = 0; |
526 | |
527 if(knob.p.x > 0) | |
528 drawKnob(screen,knob); | |
529 | |
500 if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); | 530 if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); |
501 | 531 |
502 SDL_Flip(screen); | 532 SDL_Flip(screen); |
503 } | 533 } |
504 | 534 |
513 SDL_Surface *screen; | 543 SDL_Surface *screen; |
514 SDL_Event event; | 544 SDL_Event event; |
515 | 545 |
516 int keypress = 0; | 546 int keypress = 0; |
517 int h=0,s=1,i,j; | 547 int h=0,s=1,i,j; |
548 | |
549 //gesture variables | |
550 int numDownFingers = 0; | |
551 float gdtheta = 0,gdDist = 0; | |
552 Point centroid; | |
553 knob.r = .1; | |
554 knob.ang = 0; | |
555 TouchPoint gestureLast[MAXFINGERS]; | |
556 for(i = 0;i < MAXFINGERS;i++) | |
557 gestureLast[i].f.id = -1; | |
558 | |
518 | 559 |
519 memset(keystat,0,512*sizeof(keystat[0])); | 560 memset(keystat,0,512*sizeof(keystat[0])); |
520 if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1; | 561 if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1; |
521 | 562 |
522 if (!(screen = initScreen(WIDTH,HEIGHT))) | 563 if (!(screen = initScreen(WIDTH,HEIGHT))) |
583 finger[i].p.y = ((float)event.tfinger.y)/ | 624 finger[i].p.y = ((float)event.tfinger.y)/ |
584 inTouch->yres; | 625 inTouch->yres; |
585 | 626 |
586 finger[i].pressure = | 627 finger[i].pressure = |
587 ((float)event.tfinger.pressure)/inTouch->pressureres; | 628 ((float)event.tfinger.pressure)/inTouch->pressureres; |
588 | 629 /* |
589 printf("Finger: %i, Pressure: %f Pressureres: %i\n", | 630 printf("Finger: %i, Pressure: %f Pressureres: %i\n", |
590 event.tfinger.fingerId, | 631 event.tfinger.fingerId, |
591 finger[i].pressure, | 632 finger[i].pressure, |
592 inTouch->pressureres); | 633 inTouch->pressureres); |
634 */ | |
593 //printf("Finger: %i, pressure: %f\n",event.tfinger.fingerId, | 635 //printf("Finger: %i, pressure: %f\n",event.tfinger.fingerId, |
594 // finger[event.tfinger.fingerId].pressure); | 636 // finger[event.tfinger.fingerId].pressure); |
595 } | 637 } |
596 | 638 |
597 break; | 639 break; |
617 } | 659 } |
618 finger[i].p.x = -1; | 660 finger[i].p.x = -1; |
619 finger[i].p.y = -1; | 661 finger[i].p.y = -1; |
620 break; | 662 break; |
621 } | 663 } |
664 | |
665 | |
666 if(event.type == SDL_FINGERMOTION || | |
667 event.type == SDL_FINGERDOWN || | |
668 event.type == SDL_FINGERUP) { | |
669 SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId); | |
670 //SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId); | |
671 | |
672 float x = ((float)event.tfinger.x)/inTouch->xres; | |
673 float y = ((float)event.tfinger.y)/inTouch->yres; | |
674 int j,empty = -1; | |
675 | |
676 for(j = 0;j<MAXFINGERS;j++) { | |
677 if(gestureLast[j].f.id == event.tfinger.fingerId) { | |
678 if(event.type == SDL_FINGERUP) { | |
679 numDownFingers--; | |
680 if(numDownFingers <= 1) { | |
681 gdtheta = 0; | |
682 gdDist = 0; | |
683 } | |
684 gestureLast[j].f.id = -1; | |
685 break; | |
686 } | |
687 else { | |
688 float dx = x - gestureLast[j].f.p.x; | |
689 float dy = y - gestureLast[j].f.p.y; | |
690 centroid.x = centroid.x + dx/numDownFingers; | |
691 centroid.y = centroid.y + dy/numDownFingers; | |
692 if(numDownFingers > 1) { | |
693 Point lv; //Vector from centroid to last x,y position | |
694 Point v; //Vector from centroid to current x,y position | |
695 lv = gestureLast[j].cv; | |
696 float lDist = sqrt(lv.x*lv.x + lv.y*lv.y); | |
697 printf("lDist = %f\n",lDist); | |
698 v.x = x - centroid.x; | |
699 v.y = y - centroid.y; | |
700 gestureLast[j].cv = v; | |
701 float Dist = sqrt(v.x*v.x+v.y*v.y); | |
702 // cos(dTheta) = (v . lv)/(|v| * |lv|) | |
703 | |
704 lv.x/=lDist; | |
705 lv.y/=lDist; | |
706 v.x/=Dist; | |
707 v.y/=Dist; | |
708 float dtheta = atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y); | |
709 | |
710 float dDist = (Dist - lDist); | |
711 if(lDist == 0) {dDist = 0;dtheta = 0;} | |
712 gestureLast[j].dDist = dDist; | |
713 gestureLast[j].dtheta = dtheta; | |
714 | |
715 printf("dDist = %f, dTheta = %f\n",dDist,dtheta); | |
716 //gdtheta = gdtheta*.9 + dtheta*.1; | |
717 //gdDist = gdDist*.9 + dDist*.1 | |
718 knob.r += dDist/numDownFingers; | |
719 knob.ang += dtheta; | |
720 //printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist); | |
721 //printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist); | |
722 } | |
723 else { | |
724 gestureLast[j].dDist = 0; | |
725 gestureLast[j].dtheta = 0; | |
726 gestureLast[j].cv.x = 0; | |
727 gestureLast[j].cv.y = 0; | |
728 } | |
729 gestureLast[j].f.p.x = x; | |
730 gestureLast[j].f.p.y = y; | |
731 break; | |
732 //pressure? | |
733 } | |
734 } | |
735 else if(gestureLast[j].f.id == -1 && empty == -1) { | |
736 empty = j; | |
737 } | |
738 } | |
739 | |
740 if(j >= MAXFINGERS && empty >= 0) { | |
741 printf("Finger Down!!!\n"); | |
742 numDownFingers++; | |
743 centroid.x = (centroid.x*(numDownFingers - 1) + x)/numDownFingers; | |
744 centroid.y = (centroid.y*(numDownFingers - 1) + y)/numDownFingers; | |
745 | |
746 j = empty; | |
747 gestureLast[j].f.id = event.tfinger.fingerId; | |
748 gestureLast[j].f.p.x = x; | |
749 gestureLast[j].f.p.y = y; | |
750 gestureLast[j].cv.x = 0; | |
751 gestureLast[j].cv.y = 0; | |
752 } | |
753 | |
754 //draw the touch: | |
755 } | |
756 //And draw | |
757 if(numDownFingers > 1) | |
758 knob.p = centroid; | |
759 else | |
760 knob.p.x = -1; | |
622 } | 761 } |
623 //And draw | |
624 DrawScreen(screen,h); | 762 DrawScreen(screen,h); |
625 | 763 //printf("c: (%f,%f)\n",centroid.x,centroid.y); |
764 //printf("numDownFingers: %i\n",numDownFingers); | |
626 //for(i=0;i<512;i++) | 765 //for(i=0;i<512;i++) |
627 // if(keystat[i]) printf("%i\n",i); | 766 // if(keystat[i]) printf("%i\n",i); |
628 | 767 |
629 | 768 |
630 } | 769 } |
631 SDL_Quit(); | 770 SDL_Quit(); |
632 | 771 |
633 return 0; | 772 return 0; |
634 } | 773 } |