chiark / gitweb /
debian/changelog: Start work on sensitivity
[xf86-input-mtrack.git] / src / trig.c
1 /***************************************************************************
2  *
3  * Multitouch X driver
4  * Copyright (C) 2011 Ryan Bourgeois <bluedragonx@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  **************************************************************************/
21
22 #include "trig.h"
23 #include "common.h"
24 #include <math.h>
25
26 /* Convert a radians value into an mtrack angle.
27  */
28 static double trig_encode_radians(double radians) {
29         double angle = (radians / M_PI) * 4;
30         if (angle < 0)
31                 angle = angle + 8;
32         return angle;
33 }
34
35 /* Convert an mtrack angle value into radians.
36  */
37 static double trig_decode_radians(double angle) {
38         if (angle < 4)
39                 return (angle * M_PI) / 4;
40         else
41                 return ((8 - angle) * M_PI) / -4;
42 }
43
44 double trig_direction(double dx, double dy) {
45         double angle = TR_NONE;
46         if (dx != 0 || dy != 0)
47                 return trig_encode_radians(atan2(dx, dy*-1));
48         return angle;
49 }
50
51 int trig_generalize(double dir)
52 {
53         if (dir == -1)
54                 return TR_NONE;
55         else if (dir > 1 && dir <= 3)
56                 return TR_DIR_RT;
57         else if (dir > 3 && dir <= 5)
58                 return TR_DIR_DN;
59         else if (dir > 5 && dir <= 7)
60                 return TR_DIR_LT;
61         else
62                 return TR_DIR_UP;
63 }
64
65 double trig_angles_add(double a1, double a2)
66 {
67         double a = MODVAL(a1 + a2, 8.0);
68         if (a < 0)
69                 a = a + 8.0;
70         return a;
71 }
72
73 double trig_angles_sub(double a1, double a2)
74 {
75         return trig_angles_add(a1, -1.0*a2);
76 }
77
78 double trig_angles_acute(double a1, double a2)
79 {
80         double angle;
81         if (a1 > a2)
82                 angle = trig_angles_sub(a1, a2);
83         else
84                 angle = trig_angles_sub(a2, a1);
85         if (angle > 4)
86                 angle = 8 - angle;
87         return angle;
88 }
89
90 double trig_angles_avg(double* angles, int len)
91 {
92         int i;
93         double dx, dy, r;
94         dx = dy = 0;
95         for (i = 0; i < len; i++) {
96                 r = trig_decode_radians(angles[i]);
97                 dx += cos(r);
98                 dy += sin(r);
99         }
100         return trig_encode_radians(atan2(dy, dx));
101 }
102
103 int trig_angles_cmp(double a1, double a2)
104 {
105         double m1, m2;
106         m1 = MODVAL(a1, 8);
107         m2 = MODVAL(a2, 8);
108         if (m1 == m2)
109                 return 0;
110         else if (m1 > m2)
111                 return 1;
112         else
113                 return -1;
114 }