diff options
Diffstat (limited to 'locate.c')
-rw-r--r-- | locate.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/locate.c b/locate.c new file mode 100644 index 0000000..1d3ec72 --- /dev/null +++ b/locate.c | |||
@@ -0,0 +1,91 @@ | |||
1 | #include <math.h> | ||
2 | #include <stdio.h> | ||
3 | |||
4 | #include "gm.h" | ||
5 | |||
6 | static wii_pt bounds[2][4]; | ||
7 | static int g_calibrated[4]; | ||
8 | |||
9 | double get_dist( wii_pt *p1, wii_pt *p2 ) { | ||
10 | double d = (p1->x - p2->x)*(p1->x - p2->x) + | ||
11 | (p1->y - p2->y)*(p1->y - p2->y); | ||
12 | return sqrt(d); | ||
13 | } | ||
14 | |||
15 | /* This call stores information about the expected | ||
16 | rectangle for each wii | ||
17 | */ | ||
18 | void wii_calibrate( int wii_id, wii_pt *coords ) { | ||
19 | double max_dist = 0.0; | ||
20 | int pt1 = 0, pt2 = 0, i, j; | ||
21 | |||
22 | /* Points with maximal distance span a rectangle */ | ||
23 | for( i=0; i<4; ++i ) | ||
24 | for( j=1; j<4; ++j ) { | ||
25 | double dist = get_dist( coords+i, coords+j ); | ||
26 | if( dist > max_dist ) { | ||
27 | pt1 = i; pt2 = j; | ||
28 | max_dist = dist; | ||
29 | } | ||
30 | } | ||
31 | |||
32 | if( coords[pt1].x > coords[pt2].x ) { | ||
33 | bounds[0][wii_id] = coords[pt1]; | ||
34 | bounds[1][wii_id] = coords[pt2]; | ||
35 | } else { | ||
36 | bounds[1][wii_id] = coords[pt1]; | ||
37 | bounds[0][wii_id] = coords[pt2]; | ||
38 | } | ||
39 | |||
40 | g_calibrated[wii_id] = 1; | ||
41 | } | ||
42 | |||
43 | int wii_point_to_led( int wii_id, wii_pt *coords ) { | ||
44 | // Ick nenn die immer so. | ||
45 | const double x0 = bounds[0][wii_id].x; | ||
46 | const double y0 = bounds[0][wii_id].y; | ||
47 | const double x1 = bounds[1][wii_id].x; | ||
48 | const double y1 = bounds[1][wii_id].y; | ||
49 | const double xp = coords->x; | ||
50 | const double yp = coords->y; | ||
51 | |||
52 | //printf( "%lf:%lf ", xp, yp ); | ||
53 | |||
54 | // Where m is slope of orthogonal line | ||
55 | // And n is square of diagonal of bounding box | ||
56 | double m = (x1-x0)*(xp-x0)+(y1-y0)*(yp-y0); | ||
57 | double n = (x1-x0)*(x1-x0)+(y1-y0)*(y1-y0); | ||
58 | |||
59 | // To find out distance of coord to our base line | ||
60 | double q = (xp-x0)*(y1-y0)-(yp-y0)*(x1-x0); | ||
61 | |||
62 | //printf( "%lf %lf %lf\n", m, n, q ); | ||
63 | |||
64 | double offs_on_line = m/n; | ||
65 | double dist_to_line = q/n; | ||
66 | |||
67 | // If wii is not calibrated, we cannot detect point | ||
68 | if( !g_calibrated[wii_id] ) | ||
69 | return -1; | ||
70 | |||
71 | // Point is too far away to be considered a match | ||
72 | if( ( dist_to_line > 0.1 ) || ( dist_to_line < -0.1 ) ) { | ||
73 | // puts( "too far " ); | ||
74 | return -1; | ||
75 | } | ||
76 | |||
77 | // printf( "%1.3lf\n", offs_on_line ); | ||
78 | |||
79 | // Check, which segment our line hits | ||
80 | if( ( offs_on_line > (-1.0/6.0) ) && ( offs_on_line <= (1.0/6.0) ) ) | ||
81 | return 0; | ||
82 | if( ( offs_on_line > ( 1.0/6.0) ) && ( offs_on_line <= (3.0/6.0) ) ) | ||
83 | return 1; | ||
84 | if( ( offs_on_line > ( 3.0/6.0) ) && ( offs_on_line <= (5.0/6.0) ) ) | ||
85 | return 2; | ||
86 | if( ( offs_on_line > ( 5.0/6.0) ) && ( offs_on_line <= (7.0/6.0) ) ) | ||
87 | return 3; | ||
88 | |||
89 | // No match! | ||
90 | return -1; | ||
91 | } | ||