summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSascha Hlusiak <saschahlusiak@arcor.de>2012-10-06 18:28:53 +0200
committerSascha Hlusiak <saschahlusiak@arcor.de>2013-01-16 10:50:40 +0100
commit819ba33c9d7440cd40e1e54a9b1e073ed89353a7 (patch)
tree3084010245e26f3ffe8faaa88fa3f45f88649d87
parent342057bf38e2da46609ed2fa0d3f5fb46c8ed215 (diff)
jast_axis: tune accelerated axis transformation to better work with circular axis fields
reference: https://bugs.freedesktop.org/show_bug.cgi?id=42399 joysticks with a rectangular field have a corner position of (32768,32768), joysticks with a circular field have (23170,23170). make sure that diagonal movement feels fast. either: 1) linear f(32768) ~= f(23170) + f(23170) f(32768) ~= a * f(23170) a = 2.0 on circular joysticks, the time needed for xy movement is exactly the time needed for x + the time for y separately. absolute diagonal travel speed (in cm/s) is 0.707 times as fast, which feels pretty slow. on square joysticks, diagonal travel speed is always 1.41 times faster than orthogonal travel speed. time needed for diagonal movement is always 0.5 times as long as for orthogonal movement. the value of a = 2.0 results in a nice, non-linear acceleration. or 2) trigonometric f(32768) ~= sqrt(f(23170)^2 + f(23170)^2)) f(32768) ~= a * f(23170) a = 1.414 on circular joysticks, the absolute pointer travel speed (in cm/s) is now the same for both linear and diagonal movement, which feels natural. moving diagonally takes 0.707 times the time of moving orthogonally. on square joysticks, values are as in 1) the value of a = 1.414 results in linear acceleration, which feels too slow. to maintain non-linear acceleration, make sure that: a >>= 1.414 the following formula achieves results inbetween, so it should feel natural on both devices while maintaining a nice acceleration: f(32768) ~= 1.620 * f(23170)
-rw-r--r--src/jstk_axis.c57
1 files changed, 55 insertions, 2 deletions
diff --git a/src/jstk_axis.c b/src/jstk_axis.c
index 95ebfe9..cb4a004 100644
--- a/src/jstk_axis.c
+++ b/src/jstk_axis.c
@@ -82,9 +82,62 @@ jstkAxisTimer(OsTimerPtr timer,
/* Calculate scale value, so we get a range from 0 to 32768 */
scale = (32768.0f / (float)(32768 - axis->deadzone));
+ /* NOTE: joysticks with a rectangular field have a
+ * corner position of (32768,32768), joysticks with a
+ * circular field have (23170,23170).
+ *
+ * make sure that diagonal movement feels fast. either:
+ * 1) linear
+ *
+ * f(32768) ~= f(23170) + f(23170)
+ * f(32768) ~= a * f(23170)
+ * a = 2.0
+ *
+ * on circular joysticks, the time needed for xy movement is
+ * exactly the time needed for x + the time for y separately.
+ * absolute diagonal travel speed (in cm/s) is 0.707 times as fast,
+ * which feels pretty slow.
+ *
+ * on square joysticks, diagonal travel speed is always 1.41 times
+ * faster than orthogonal travel speed. time needed for diagonal
+ * movement is always 0.5 times as long as for orthogonal movement.
+ *
+ * the value of a = 2.0 results in a nice, non-linear acceleration.
+ *
+ * or
+ * 2) trigonometric
+ *
+ * f(32768) ~= sqrt(f(23170)^2 + f(23170)^2))
+ * f(32768) ~= a * f(23170)
+ * a = 1.414
+ *
+ * on circular joysticks, the absolute pointer travel speed
+ * (in cm/s) is now the same for both linear and diagonal movement,
+ * which feels natural. moving diagonally takes 0.707 times the time
+ * of moving orthogonally.
+ *
+ * on square joysticks, values are as in 1)
+ *
+ * the value of a = 1.414 results in linear acceleration, which feels
+ * too slow.
+ *
+ * to maintain non-linear acceleration, make sure that:
+ *
+ * a >>= 1.414
+ *
+ * the following formula achieves results inbetween,
+ * so it should feel natural on both devices while maintaining a
+ * nice acceleration:
+ *
+ * f(32768) ~= 1.620 * f(23170)
+ *
+ * TODO: make this simpler by using only values -1.0..1.0 and
+ * provide acceleration graphs.
+ */
+
/* How many pixels should this axis move the cursor */
- p1 = ((pow((abs((float)axis->value) - (float)axis->deadzone) *
- scale / 1700.0f, 3.4f)) + 100.0f) *
+ p1 = (pow((abs((float)axis->value) - (float)axis->deadzone) *
+ scale / 23, 1.4f) + 100.0f) *
((float)NEXTTIMER / 40000.0f);
/* How many "pixels" should this axis scroll */
p2 = ((pow((abs((float)axis->value) - (float)axis->deadzone) *