summaryrefslogtreecommitdiff
path: root/heuristics.c
diff options
context:
space:
mode:
authorerdgeist <>2008-09-16 15:40:46 +0000
committererdgeist <>2008-09-16 15:40:46 +0000
commit8d957f068792b4ee55f807930c975699c29922a2 (patch)
tree4a960cbe6c05797175a7c8b518f93e4459bafd1d /heuristics.c
KickoffHEADmaster
Diffstat (limited to 'heuristics.c')
-rw-r--r--heuristics.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/heuristics.c b/heuristics.c
new file mode 100644
index 0000000..429a612
--- /dev/null
+++ b/heuristics.c
@@ -0,0 +1,111 @@
1#include <stdio.h>
2
3#include "vubars.h"
4
5static void heuristics_getGesture( int const amount, int const off, int const * const values,
6 int *dxl, int *dyl, int *dxr, int *dyr );
7
8int heuristics_getEnergy( int const amount, int const * const values ) {
9 int energy = 0;
10 int i;
11
12 for( i = 0; i < amount-1; ++i )
13 energy += values[i]*values[i+1];
14
15 return energy;
16}
17
18// Gets the two longest consecutive gestures found
19// in frames. -1 in off[ab] means no gesture found
20
21// Here what counts: the bigger abs(dx[ab]), the longer the gesture
22// the bigger dy[ab]/dx[ab], the slower the gesture
23void heuristics_getGestures( int const amount, int const * const values,
24 int *offa, int *dxa, int *dya, int *dda,
25 int *offb, int *dxb, int *dyb, int *ddb )
26{
27 int i, l = 0;
28 int dxl [ amount ], dyl [ amount ], dxr [ amount ], dyr [ amount ];
29
30 // Get the longest gestures for each point - both into left and rite
31 for( i=0; i<amount; ++i )
32 heuristics_getGesture( amount, i, values, dxl + i, dyl + i, dxr + i, dyr + i );
33
34 // "Sort" gesture by length
35 *offa = *dxa = *dya = 0;
36 for( i=0; i<amount; ++i ) {
37 if( dxr[ i ] > *dxa ) { *offa = i; *dxa = dxr[ i ]; *dya = dyr[ i ]; *dda = 1; }
38 if( dxl[ i ] > *dxa ) { *offa = i; *dxa = dxl[ i ]; *dya = dyl[ i ]; *dda =-1; }
39 }
40
41 // If no gesture found at all, invalidate off
42 // and return... second run wouldnt suddenly find a gesture
43 if( *dxa == 0 ) { *offa = *offb = -1; return; }
44
45 // Now clear the best result - this will find us the second best result
46 i = *offa;
47 if( *dda == 1 ) {
48 for( i=*offa; i < *offa + dxr[ *offa ]; ++i )
49 dxr[ i ] = 0;
50 } else {
51 for( i=*offa; i > *offa - dxl[ *offa ]; --i )
52 dxl[ i ] = 0;
53 }
54
55 // "Sort" remaining gestures by length
56 *offb = *dxb = *dyb = 0;
57 for( i=0; i<amount; ++i ) {
58 if( dxr[ i ] > *dxb ) { *offb = i; *dxb = dxr[ i ]; *dyb = dyr[ i ]; *ddb = 1;}
59 if( dxl[ i ] > *dxb ) { *offb = i; *dxb = -dxl[ i ]; *dyb = dyl[ i ]; *ddb =-1;}
60 }
61
62 // If no secondary gesture found, invalidate off
63 if( *dxb == 0 ) *offb = -1;
64}
65
66static void heuristics_getGesture( int const amount, int const off, int const * const values,
67 int * const dxl, int * const dyl, int * const dxr, int * const dyr )
68{
69 int i;
70
71 // Initialize as "nothing happened"
72 *dxl = *dxr = *dyl = *dyr = 0;
73
74 // if this didn't peak in last frame, we're not starting
75 // a gesture here.
76 if( values[off] != VU_PEAK ) return;
77
78 if( off > 0 ) *dyl = values[off]-values[off-1];
79 if( off < amount-1 ) *dyr = values[off]-values[off+1];
80
81 if( !*dyl && !*dyr ) return;
82
83 // Depending on where this peaks seems to have come from,
84 // chose direction where to follow it
85 // try to collect enough monotonic samples and calculate a
86 // slope. Since our sample peaks, all others cant be larger
87 if( (*dyl) && (*dyl < *dyr) ) {
88 (*dxl)++;
89 for( i=off-1; i>=0; --i ) {
90 int dy = values[i+1] - values[i];
91
92 // If it scrolled out of scope, ignore it
93 if( !values[i] || dy < 0 ) break;
94
95 (*dxl)++;
96 (*dyl) += dy;
97 }
98 } else {
99 (*dxr)++;
100 // Do the same when going right
101 for( i=off+1; i<amount; ++i ) {
102 int dy = values[i-1] - values[i];
103
104 // If it scrolled out of scope, ignore it
105 if( !values[i] || dy < 0 ) break;
106
107 (*dxr)++;
108 (*dyr) += dy;
109 }
110 }
111}