middleware/src/Tracking/Gestures/UserPositionDetector.cs
author bastiena
Tue, 20 Mar 2012 18:00:55 +0100
changeset 7 8a21bec5d45f
parent 6 93dfb08dcc97
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).

/*
 * Projet : TraKERS
 * Module : MIDDLEWARE
 * Sous-Module : Tracking/Gestures
 * Classe : UserPositionDetector
 * 
 * Auteur : alexandre.bastien@iri.centrepompidou.fr
 * 
 * Fonctionnalités : Permet de détecter si l'utilisateur s'est déplacé dans la zone de détection, en se basant
 * sur la distance de l'utilisateur à Kinect.
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Trakers.Tracking.Gestures
{
    public class UserPositionDetector
    {
        Debug.DebugWindow debug;

        float minDistance, maxDistance, zeroPoint;
        float searchMinDistance, searchMaxDistance;

        static int n = 0;

        /*
         * Le constructeur prend en entrée le debug mais aussi les principales distances qui délimitent la
         * zone de détection.
         */
        public UserPositionDetector(Debug.DebugWindow _d, float _minDistance, float _maxDistance, float _zeroPoint, float _searchMinDistance, float _searchMaxDistance)
        {
            minDistance = _minDistance;
            maxDistance = _maxDistance;
            searchMinDistance = _searchMinDistance;
            searchMaxDistance = _searchMaxDistance;
            zeroPoint = _zeroPoint;
            debug = _d;
        }

        /*
         * Getters et Setters des distances (dans le cadre d'une modification des paramètres).
         */
        public void setMinDistance(float dist)
        {
            minDistance = dist;
        }
        public void setMaxDistance(float dist)
        {
            maxDistance = dist;
        }
        public void setSearchMinDistance(float dist)
        {
            searchMinDistance = dist;
        }
        public void setSearchMaxDistance(float dist)
        {
            searchMaxDistance = dist;
        }
        public void setZeroPoint(float dist)
        {
            zeroPoint = dist;
        }
        public void setParams(float minDist, float maxDist, float minDistHands, float maxDistHands, float zero)
        {
            //On charge tous les paramètres d'un coup.
            minDistance = minDist;
            maxDistance = maxDist;
            searchMinDistance = minDistHands;
            searchMaxDistance = maxDistHands;
            zeroPoint = zero;
        }

        public float getMinDistance()
        {
            return minDistance;
        }
        public float getMaxDistance()
        {
            return maxDistance;
        }
        public float getSearchMinDistance()
        {
            return searchMinDistance;
        }
        public float getSearchMaxDistance()
        {
            return searchMaxDistance;
        }
        public float getZeroPoint()
        {
            return zeroPoint;
        }

        /*
         * Lit la position de l'utilisateur à Kinect et ressort un pourcentage de proximité.
         * Règles : Droite affine de coefficient négatif.
         * .
         */
        public float CalcProximity(float distance)
        {
            //Si on se trouve trop loin.
            if (distance > maxDistance)
                return 0.0f;
            //Si on se trouve trop près.
            if (distance < searchMinDistance)
                return 0.0f;
            //Si on n'est pas encore trop près mais qu'on dépasse le point zéro.
            if (distance < zeroPoint)
                return 100.0f;

            //Equation, de droite affine à partir de deux points.
            //Ici 99 tout simplement car 100 - 1, les limites de pourcentage de proximité.
            float a = 99/((float)zeroPoint - maxDistance);
            float b = 100 - a * zeroPoint;

            return a * distance + b;
        }

        /*
         * Estime le nombre de vidéos à afficher en fonction du pourcentage de proximité et du nombre de
         * vidéos dans la mosaïque.
         * .
         */
        public int ImagesToShow(float proximity, int N)
        {
            //Si la proximité est nulle, on retourne 0.
            if (proximity == 0f)
                return 0;
            //Si on n'est pas encore trop près mais qu'on dépasse le point zéro.
            if (proximity >= 90f)
                return N;

            //Pour chaque intervalle de déciles (dans les pourcentages), le nombre de dizaines
            //du pourcentage de proximité plus un, fois le nombre de dizaines d'images seront affichées.
            return (((int)proximity / 10) + 1) * ((int)N / 2);
        }
    }
}