middleware/src/Tracking/Gestures/SwipeDetector.cs
author bastiena
Tue, 20 Mar 2012 18:00:55 +0100
changeset 7 8a21bec5d45f
parent 5 d40f84d77db4
child 8 e4e7db2435f8
permissions -rw-r--r--
Middleware : No proximity bugs anymore. The skeleton disappear if a tracked person is too close or not tracked anymore. Processing : There are no laggs anymore when an user stay too long moving his hands and drawing tons of ellipses. (TUIO Cursors are not taken by their vectors, only the last position of the cursors are caught to be drawn).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     1
/*
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     2
 * Projet : TraKERS
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     3
 * Module : MIDDLEWARE
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     4
 * Sous-Module : Tracking/Gestures
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     5
 * Classe : SwipeDetector
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     6
 * 
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     7
 * Auteur : alexandre.bastien@iri.centrepompidou.fr
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     8
 * 
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     9
 * Fonctionnalités : Permet de détecter si l'utilisateur a effectué un Swipe, en se basant sur
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    10
 * des règles appliquées à la positions des noeuds dans le temps.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    11
 */
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    12
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    13
using System;
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    14
using System.Collections.Generic;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    15
using System.Linq;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    16
using System.Text;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    17
using Microsoft.Kinect;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    18
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    19
namespace Trakers.Tracking.Gestures
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    20
{
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    21
    public class SwipeDetector : GestureDetector
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    22
    {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    23
        public enum Direction {LEFT, RIGHT, TOP, DOWN};
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    24
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    25
        Debug.DebugWindow debug;
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    26
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    27
        public SwipeDetector(Debug.DebugWindow _d) : base()
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    28
        {
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    29
            debug = _d;
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    30
            gesturePeriod = (float)0.5;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    31
            indexesPerSecond = 30;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    32
            indexesToCheck = (int)(gesturePeriod * indexesPerSecond);
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    33
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    34
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    35
        /*
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    36
         * Lit les noeuds de l'historique du squelette afin de détecter un Swipe left.
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    37
         * Règles :
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    38
         * Se fait avec la main droite.
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    39
         * Chaque nouvelle position de la main doit être à la gauche de la précédente.
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    40
         * Chaque nouvelle position de la main ne doit pas s'éloigner verticalement de plus d'une certaine distance.
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    41
         * Le geste doit mesurer horizontalement une certaine distance.
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    42
         */
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    43
        public bool CheckForSwipeLeft()
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    44
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    45
            //Crée un historique de squelette local, puisque l'historique est mis à jour toutes les ~1/30 s.
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    46
            List<List<Joint>> localHistory = new List<List<Joint>>(history);
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    47
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    48
            //Si il n'y a pas assez de positions dans l'historique local pour vérifier le geste.
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    49
            if (localHistory.Count < indexesToCheck+1)
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    50
                return false;
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    51
            
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    52
            //La distance de référence est ici la distance entre le milieu du dos et le milieu des épaules.
5
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
    53
            refDistance = Math.Abs(localHistory[0][(int)JointType.Spine].Position.Y - localHistory[0][(int)JointType.ShoulderCenter].Position.Y);
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    54
            //On commence la position pour les indexesToCheck dernières postures (celle à l'index 0 étant la dernière).
5
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
    55
            startPoint = localHistory[localHistory.Count - indexesToCheck][(int)JointType.HandRight].Position;
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    56
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    57
            //De la position p1 à pn, on suit l'algorithme.
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    58
            for (int i = localHistory.Count - indexesToCheck + 1; i < localHistory.Count; i++)
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    59
            {
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    60
                //Si la position Y de la main est plus haute que la tête
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    61
                //OU si la position Y de la main est plus basse que la hanche
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    62
                //OU si la nouvelle position X de la main est à droite de la précédente
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    63
                //OU si la nouvelle position Y de la main est plus éloignée de la distance N par rapport à la première position Y
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    64
                //Alors on retourne faux.
5
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
    65
                if (localHistory[i][(int)JointType.HandRight].Position.Y < localHistory[i][(int)JointType.Head].Position.Y ||
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
    66
                localHistory[i][(int)JointType.HandRight].Position.Y > localHistory[i][(int)JointType.HipCenter].Position.Y ||
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
    67
                localHistory[i][(int)JointType.HandRight].Position.X > localHistory[i - 1][(int)JointType.HandRight].Position.X ||
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
    68
                Math.Abs(localHistory[i][(int)JointType.HandRight].Position.Y - startPoint.Y) > refDistance / 2)
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    69
                    return false;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    70
            }
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    71
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    72
            //Si la distance horizontale du geste a été plus courte que la distance N
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    73
            //Alors on retourne faux.
5
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
    74
            if (Math.Abs(localHistory[0][(int)JointType.HandRight].Position.X - localHistory[localHistory.Count - indexesToCheck][(int)JointType.HandRight].Position.X) < refDistance / 2)
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    75
                return false;
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    76
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    77
            //Si la dernière position de la main droite est sur le côté droit du corps
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    78
            //OU si la première position calculée de la main droite est sur le côté gauche du corps
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    79
            //Alors on retourne faux.
5
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
    80
            if (localHistory[localHistory.Count - 1][(int)JointType.HandRight].Position.X > localHistory[localHistory.Count - 1][(int)JointType.HipCenter].Position.X ||
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
    81
               localHistory[localHistory.Count - indexesToCheck][(int)JointType.HandRight].Position.X < localHistory[localHistory.Count - 1][(int)JointType.HipCenter].Position.X)
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    82
                return false;
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    83
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    84
            //On supprime l'historique local.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    85
            localHistory.Clear();
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    86
            //Si on est arrivé jusqu'ici, toutes les conditions pour un swipe left ont été remplies.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    87
            return true;
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    88
        }
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    89
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    90
        /*
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    91
         * Lit les noeuds de l'historique du squelette afin de détecter un Swipe right.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    92
         * Règles :
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    93
         * Se fait avec la main gauche.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    94
         * Chaque nouvelle position de la main doit être à la droite de la précédente.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    95
         * Chaque nouvelle position de la main ne doit pas s'éloigner verticalement de plus d'une certaine distance.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    96
         * Le geste doit mesurer horizontalement une certaine distance.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    97
         */
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    98
        public bool CheckForSwipeRight()
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    99
        {
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   100
            //Crée un historique de squelette local, puisque l'historique est mis à jour toutes les ~1/30 s.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   101
            List<List<Joint>> localHistory = new List<List<Joint>>(history);
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   102
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   103
            //Si il n'y a pas assez de positions dans l'historique local pour vérifier le geste.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   104
            if (localHistory.Count < indexesToCheck + 1)
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   105
                return false;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   106
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   107
            //La distance de référence est ici la distance entre le milieu du dos et le milieu des épaules.
5
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
   108
            refDistance = Math.Abs(localHistory[0][(int)JointType.Spine].Position.Y - localHistory[0][(int)JointType.ShoulderCenter].Position.Y);
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   109
            //On commence la position pour les indexesToCheck dernières postures (celle à l'index 0 étant la dernière).
5
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
   110
            startPoint = localHistory[localHistory.Count - indexesToCheck][(int)JointType.HandLeft].Position;
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   111
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   112
            //De la position p1 à pn, on suit l'algorithme.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   113
            for (int i = localHistory.Count - indexesToCheck + 1; i < localHistory.Count; i++)
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   114
            {
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   115
                //Si la position Y de la main est plus haute que la tête
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   116
                //OU si la position Y de la main est plus basse que la hanche
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   117
                //OU si la nouvelle position X de la main est à gauche de la précédente
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   118
                //OU si la nouvelle position Y de la main est plus éloignée de la distance N par rapport à la première position Y
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   119
                //Alors on retourne faux.
5
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
   120
                if (localHistory[i][(int)JointType.HandLeft].Position.Y < localHistory[i][(int)JointType.Head].Position.Y ||
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
   121
                localHistory[i][(int)JointType.HandLeft].Position.Y > localHistory[i][(int)JointType.HipCenter].Position.Y ||
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
   122
                localHistory[i][(int)JointType.HandLeft].Position.X < localHistory[i - 1][(int)JointType.HandLeft].Position.X ||
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
   123
                Math.Abs(localHistory[i][(int)JointType.HandLeft].Position.Y - startPoint.Y) > refDistance / 2)
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   124
                    return false;
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   125
            }
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   126
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   127
            //Si la distance horizontale du geste a été plus courte que la distance N
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   128
            //Alors on retourne faux.
5
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
   129
            if (Math.Abs(localHistory[0][(int)JointType.HandLeft].Position.X - localHistory[localHistory.Count - indexesToCheck][(int)JointType.HandLeft].Position.X) < refDistance / 2)
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   130
                return false;
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   131
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   132
            //Si la dernière position de la main droite est sur le côté gauche du corps
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   133
            //OU si la première position calculée de la main droite est sur le côté droit du corps
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   134
            //Alors on retourne faux.
5
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
   135
            if (localHistory[localHistory.Count - 1][(int)JointType.HandLeft].Position.X < localHistory[localHistory.Count - 1][(int)JointType.HipCenter].Position.X ||
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
   136
               localHistory[localHistory.Count - indexesToCheck][(int)JointType.HandLeft].Position.X > localHistory[localHistory.Count - 1][(int)JointType.HipCenter].Position.X)
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   137
                return false;
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   138
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   139
            //On supprime l'historique local.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   140
            localHistory.Clear();
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   141
            //Si on est arrivé jusqu'ici, toutes les conditions pour un swipe right ont été remplies.
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   142
            return true;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   143
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   144
    }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   145
}