public bool processConstHandLeftGesture(GestureDatabase gestureDatabase)
        {
            if (gestureDatabase.getTotalSize() > 0)
            {
                if (!isConstLeftHandGestureStarted && indexOfFirstValidConstLeftGestureFrame < 0)
                {
                    bool isCurrentValidStartFrame = isFirstValidGestureFrame(GESTURE.CONST_LEFT, gestureDatabase);
                    if (!isCurrentValidStartFrame)
                    {
                        reset(GESTURE.CONST_LEFT);
                        return false;
                    }
                    isConstLeftHandGestureStarted = true;
                    indexOfFirstValidConstLeftGestureFrame = indexOfLastValidConstLeftGestureFrame = gestureDatabase.getTotalSize() - 1;
                    startTimerConstLeftHand = DateTime.Now;
                    return false;                   // is valid gesture frame , but gesture is still incomplete , so return false.
                }
            }
            else
                return false;

            // check to see if the current frame is a valid frame
            bool isCurrentFrameValid = isIntermediaryFrameValidGestureFrame(GESTURE.CONST_LEFT, gestureDatabase);
            if (!isCurrentFrameValid)
            {
                reset(GESTURE.CONST_LEFT);
                return false;
            }

            // check for nobody movement by comparing frames first and lastvalid frames
            bool isBodyDeflectionValid = isBodyLinearDeflectionsWithInBounds(GESTURE.CONST_LEFT,  gestureDatabase);
            if (!isBodyDeflectionValid)
            {
                reset(GESTURE.CONST_LEFT);
                return false;
            }

               // all conditions satisfied , now check if the gesture has completed , update the indexOfLastValidFrame and Update the time

            indexOfLastValidConstLeftGestureFrame++;
            currentTimerConstLeftHand = DateTime.Now;
            timeElapsedConstLeftHand = new TimeSpan(currentTimerConstLeftHand.Ticks - startTimerConstLeftHand.Ticks);

            if (timeElapsedConstLeftHand.Seconds >= THRESHOLD_TIME_FOR_VALID_GESTURE)
            {
                // valid gesture
                reset(GESTURE.CONST_LEFT);
                return true;
            }
            else
            {
                // gesture in progress and not complete but not an Invalid gesture
                return false;

            }
        }
Esempio n. 2
0
 public GestureEngine()
 {
     gestureDatabase = new GestureDatabase();
     swipeGestureProcessor = new SwipeGesture();
     verticalUpDownGestureProcessor = new VerticalUpDownGesture();
     pushPullGestureProcessor = new PushPullGesture();
     constHandLeftRightGestureProcessor = new ConstHandLeftRightGesture();
     tempSkeletonFrames = new Skeleton[KINECT_MAX_SKELETON_TRACKABLE];
     framesSkipped = 0;
 }
Esempio n. 3
0
        public bool processSwipeLeftGesture(GestureDatabase gestureDatabase)
        {
            // check for a valid start gesture , see if the hands are with in the angle range. Start the gesture if the frame is valid
            if (gestureDatabase.getTotalSize() > 0)
            {
                if (!isSwipeLeftGestureStarted && indexOfFirstValidSwipeLeftFrame < 0)
                {
                    bool isFrameValidSwipeLeftStartFrame = isFirstValidGestureFrame(GESTURE.SWIPE_LEFT, gestureDatabase);
                    if (!isFrameValidSwipeLeftStartFrame)
                    {
                        reset(GESTURE.SWIPE_LEFT);
                        return false;
                    }

                    indexOfFirstValidSwipeLeftFrame = indexOfLastValidSwipeLeftFrame = gestureDatabase.getTotalSize() - 1;
                    isSwipeLeftGestureStarted = true;
                    startSwipeLeftTime = currentSwipeLeftTime = DateTime.Now;
                    return false;
                }

            }
            else
            {
                return false;
            }

            /*
             * <condition>
             *  See if body doesnt move
             * </condition>
            */

            bool isBodyDeflectionValid = isBodyLinearDeflectionWithInBounds(GESTURE.SWIPE_LEFT, gestureDatabase);
            if (!isBodyDeflectionValid)
            {
                // Console.WriteLine("gesture : SWIPE LEFt , invalid isBodyDeflectionValid");
                reset(GESTURE.SWIPE_LEFT);
                return false;
            }

            /*
             * <condition>
             *  See if the intermediary frames are valid for the SWIPE LEFT gesture
             * </condition>
            */
            bool isIntermediaryFrameValid = isIntermediaryFrameValidGestureFrame(GESTURE.SWIPE_LEFT, gestureDatabase);
            if (!isIntermediaryFrameValid)
            {
                // Console.WriteLine("gesture : SWIPE LEFt , invalid isIntermediaryFrameValid");
                reset(GESTURE.SWIPE_LEFT);
                return false;
            }

            /*
             * <condition>
             *  See if the movement of the hand is a valid SWIPE LEFT
             * </condition>
            */

            bool isHandAngularMovementValid = isHandAngularChangeWithInBounds(GESTURE.SWIPE_LEFT, gestureDatabase);
            if (!isHandAngularMovementValid)
            {
                // Console.WriteLine("gesture : SWIPE LEFt , invalid isHandAngularMovementValid");
                reset(GESTURE.SWIPE_LEFT);
                return false;
            }

            /*
            * <condition>
            *  See if the cumulative angle is valid SWIPE LEfT Angle , Counter ClockWise , only at an interval of multiple of 30 frames
            * </condition>
               */

            if (indexOfFirstValidSwipeLeftFrame != indexOfLastValidSwipeLeftFrame && indexOfLastValidSwipeLeftFrame % 30 == 0)
            {
                bool isIntermediaryCumulativeAngleValid = isIntermediaryCumulativeAngularMotionValid(GESTURE.SWIPE_LEFT, gestureDatabase);
                if (!isIntermediaryCumulativeAngleValid)
                {
                    // Console.WriteLine("gesture : SWIPE LEFt , invalid isIntermediaryCumulativeAngleValid");
                    reset(GESTURE.SWIPE_LEFT);
                    return false;
                }
            }

            /*
             * <Update>
             *  All conditions are satified, Update time and angle and check for gesture completion or expiration
             * </Update>
            */
            // Console.WriteLine("\ngesture : SWIPE LEFT , current Angle " + currentSwipeLeftAngle);
            // Console.WriteLine("\ngesture : SWIPE LEFT , current TIme " + swipeLeftTimeSpan.Seconds);
            currentSwipeLeftAngle = updateCurrentAngle(GESTURE.SWIPE_LEFT, gestureDatabase);
            currentSwipeLeftTime = DateTime.Now;
            swipeLeftTimeSpan = new TimeSpan(currentSwipeLeftTime.Ticks - startSwipeLeftTime.Ticks);
            indexOfLastValidSwipeLeftFrame++;

            if ((currentSwipeLeftAngle <=  SWIPE_LEFT_MIN_FINISH_ANGLE - SWIPE_LEFT_MIN_START_ANGLE) &&
                swipeLeftTimeSpan.Seconds >= THRESHOLD_TIME_FOR_VALID_GESTURE)
            {
                // gesture completed
                reset(GESTURE.SWIPE_LEFT);
                return true;
            }
            else if (swipeLeftTimeSpan.Seconds >= THRESHOLD_TIME_FOR_GESTURE_TO_EXPIRE)
            {
                // time over, gesture not completed
                reset(GESTURE.SWIPE_LEFT);
                return false;
            }

            // gesture frames are valid , just that the gesture isn't complete

            return false;
        }
Esempio n. 4
0
        private double updateCurrentAngle(GESTURE gesture , GestureDatabase gestureDatabase)
        {
            double diffAngle = 0.0;

            Skeleton lastSkeleton;
            AppropriateJointInfo lastAptJointInfo;

            Skeleton lastValidSkeleton;
            AppropriateJointInfo lastValidAptJointInfo;

            int indexOfLastValidGesture = (gesture == GESTURE.SWIPE_RIGHT) ?
                                           indexOfLastValidSwipeRightFrame :
                                           indexOfLastValidSwipeLeftFrame;

            // compare the current frame with the last valid swipe right frame
            gestureDatabase.getLastRecord(out lastSkeleton, out lastAptJointInfo);
            gestureDatabase.getRecord(indexOfLastValidGesture, out lastValidSkeleton, out lastValidAptJointInfo);

            HCI580_Geometry.Vector2D lastElbowShoulder = new HCI580_Geometry.Vector2D(
                                                           (lastAptJointInfo.shoulderRightPos.X - lastAptJointInfo.elbowRightPos.X),
                                                           (lastAptJointInfo.shoulderRightPos.Y - lastAptJointInfo.elbowRightPos.Y));

            HCI580_Geometry.Vector2D lastElbowHand = new HCI580_Geometry.Vector2D(
                                                           (lastAptJointInfo.handRightPos.X - lastAptJointInfo.elbowRightPos.X),
                                                           (lastAptJointInfo.handRightPos.Y - lastAptJointInfo.elbowRightPos.Y));

            HCI580_Geometry.Vector2D lastValidElbowShoulder = new HCI580_Geometry.Vector2D(
                                                           (lastValidAptJointInfo.shoulderRightPos.X - lastValidAptJointInfo.elbowRightPos.X),
                                                           (lastValidAptJointInfo.shoulderRightPos.Y - lastValidAptJointInfo.elbowRightPos.Y));

            HCI580_Geometry.Vector2D lastValidElbowHand = new HCI580_Geometry.Vector2D(
                                                           (lastValidAptJointInfo.handRightPos.X - lastValidAptJointInfo.elbowRightPos.X),
                                                           (lastValidAptJointInfo.handRightPos.Y - lastValidAptJointInfo.elbowRightPos.Y));

            diffAngle = lastElbowShoulder.angleTo(lastElbowHand) - lastValidElbowShoulder.angleTo(lastValidElbowHand);

            // Console.WriteLine("diff Angle " +  diffAngle);
            diffAngle = (gesture == GESTURE.SWIPE_RIGHT) ? (diffAngle < 0 ? 0 : diffAngle) : (diffAngle > 0 ? 0 : diffAngle);

            // both the angles need to be added , as the diff angle will be negative for left swipes.
            return ((gesture == GESTURE.SWIPE_RIGHT) ? this.currentSwipeRightAngle + diffAngle : this.currentSwipeLeftAngle + diffAngle);
        }
Esempio n. 5
0
        private bool isIntermediaryFrameValidGestureFrame(GESTURE gesture, GestureDatabase gestureDatabase)
        {
            Skeleton currentSkeleton;
            AppropriateJointInfo currentAptJointInfo;

            gestureDatabase.getLastRecord(out currentSkeleton, out currentAptJointInfo);

            switch (gesture)
            {
                case GESTURE.SWIPE_RIGHT:
                    {
                        HCI580_Geometry.Vector2D currentElbowShoulder = new HCI580_Geometry.Vector2D((currentAptJointInfo.shoulderRightPos.X - currentAptJointInfo.elbowRightPos.X),
                                                                                              (currentAptJointInfo.shoulderRightPos.Y - currentAptJointInfo.elbowRightPos.Y));

                        HCI580_Geometry.Vector2D currentElbowHand = new HCI580_Geometry.Vector2D((currentAptJointInfo.handRightPos.X - currentAptJointInfo.elbowRightPos.X),
                                                                                          (currentAptJointInfo.handRightPos.Y - currentAptJointInfo.elbowRightPos.Y));

                        // check if hand Y > elbow Y , angle between elbowShoulder and elbowHand negative
                        if (currentAptJointInfo.handRightPos.Y > currentAptJointInfo.elbowRightPos.Y &&
                            currentElbowShoulder.cpsign(currentElbowHand) < 0)
                        {

                            return true;

                        }
                    }
                    break;
                case GESTURE.SWIPE_LEFT:
                    {
                        HCI580_Geometry.Vector2D currentElbowShoulder = new HCI580_Geometry.Vector2D((currentAptJointInfo.shoulderRightPos.X - currentAptJointInfo.elbowRightPos.X),
                                                                                              (currentAptJointInfo.shoulderRightPos.Y - currentAptJointInfo.elbowRightPos.Y));

                        HCI580_Geometry.Vector2D currentElbowHand = new HCI580_Geometry.Vector2D((currentAptJointInfo.handRightPos.X - currentAptJointInfo.elbowRightPos.X),
                                                                                          (currentAptJointInfo.handRightPos.Y - currentAptJointInfo.elbowRightPos.Y));

                        // check if hand Y > elbow Y , angle between elbowShoulder and elbowHand negative
                        if (currentAptJointInfo.handRightPos.Y > currentAptJointInfo.elbowRightPos.Y &&
                            currentElbowShoulder.cpsign(currentElbowHand) < 0)
                        {
                            return true;
                        }
                    }
                    break;

            }
            return false;
        }
Esempio n. 6
0
        private bool isIntermediaryCumulativeAngularMotionValid(GESTURE gesture, GestureDatabase gestureDatabase)
        {
            Skeleton currentSkeleton;
            AppropriateJointInfo currentAptInfo;
            Skeleton firstValidSkeleton;
            AppropriateJointInfo firstValidAptInfo;
            int indexOfFirstValidMotion;

            indexOfFirstValidMotion =   (gesture == GESTURE.SWIPE_RIGHT) ?
                                        indexOfFirstValidSwipeRightFrame :
                                        indexOfFirstValidSwipeLeftFrame;

            gestureDatabase.getLastRecord(out currentSkeleton, out currentAptInfo);
            gestureDatabase.getRecord(indexOfFirstValidMotion,out firstValidSkeleton , out firstValidAptInfo);

            HCI580_Geometry.Vector2D currentElbowShoulder = new HCI580_Geometry.Vector2D((currentAptInfo.shoulderRightPos.X - currentAptInfo.elbowRightPos.X),
                                                                                         (currentAptInfo.shoulderRightPos.Y - currentAptInfo.elbowRightPos.Y));
            HCI580_Geometry.Vector2D currentElbowHand =     new HCI580_Geometry.Vector2D((currentAptInfo.handRightPos.X - currentAptInfo.elbowRightPos.X),
                                                                                         (currentAptInfo.handRightPos.Y - currentAptInfo.elbowRightPos.Y));

            HCI580_Geometry.Vector2D firstElbowShoulder = new HCI580_Geometry.Vector2D((firstValidAptInfo.shoulderRightPos.X - firstValidAptInfo.elbowRightPos.X),
                                                                                        (firstValidAptInfo.shoulderRightPos.Y - firstValidAptInfo.elbowRightPos.Y));
            HCI580_Geometry.Vector2D firstElbowHand = new HCI580_Geometry.Vector2D((firstValidAptInfo.handRightPos.X - firstValidAptInfo.elbowRightPos.X),
                                                                                         (firstValidAptInfo.handRightPos.Y - firstValidAptInfo.elbowRightPos.Y));

            double diffAngle =  currentElbowShoulder.angleTo(currentElbowHand) - firstElbowShoulder.angleTo(firstElbowHand);
            // Console.WriteLine("cumulative  diff " + diffAngle);
            return (gesture == GESTURE.SWIPE_RIGHT) ? (diffAngle > 0 ? true : false) : (diffAngle < 0 ? true : false);
        }
Esempio n. 7
0
        // check for too fast and opposite movements
        private bool isHandAngularChangeWithInBounds(GESTURE gesture , GestureDatabase gestureDatabase)
        {
            Skeleton lastSkeleton;
            AppropriateJointInfo lastAptJointInfo;

            Skeleton lastValidSkeleton;
            AppropriateJointInfo lastValidAptJointInfo;

            int indexOfLastValidGesture = (gesture == GESTURE.SWIPE_RIGHT) ?
                                           indexOfLastValidSwipeRightFrame :
                                           indexOfLastValidSwipeLeftFrame;

            if (indexOfLastValidGesture < 0)
            {
                return true;
            }
            // compare the current frame with the last valid swipe right frame
            gestureDatabase.getLastRecord(out lastSkeleton , out lastAptJointInfo);
            gestureDatabase.getRecord(indexOfLastValidGesture , out lastValidSkeleton , out lastValidAptJointInfo);

            HCI580_Geometry.Vector2D lastElbowShoulder = new HCI580_Geometry.Vector2D(
                                                           (lastAptJointInfo.shoulderRightPos.X - lastAptJointInfo.elbowRightPos.X) ,
                                                           (lastAptJointInfo.shoulderRightPos.Y - lastAptJointInfo.elbowRightPos.Y));

            HCI580_Geometry.Vector2D lastElbowHand = new HCI580_Geometry.Vector2D(
                                                           (lastAptJointInfo.handRightPos.X - lastAptJointInfo.elbowRightPos.X),
                                                           (lastAptJointInfo.handRightPos.Y - lastAptJointInfo.elbowRightPos.Y));

            HCI580_Geometry.Vector2D lastValidElbowShoulder = new HCI580_Geometry.Vector2D(
                                                           (lastValidAptJointInfo.shoulderRightPos.X - lastValidAptJointInfo.elbowRightPos.X),
                                                           (lastValidAptJointInfo.shoulderRightPos.Y - lastValidAptJointInfo.elbowRightPos.Y));

            HCI580_Geometry.Vector2D lastValidElbowHand  = new HCI580_Geometry.Vector2D(
                                                           (lastValidAptJointInfo.handRightPos.X - lastValidAptJointInfo.elbowRightPos.X),
                                                           (lastValidAptJointInfo.handRightPos.Y - lastValidAptJointInfo.elbowRightPos.Y));

            if (Math.Abs(lastElbowShoulder.angleTo(lastElbowHand) - lastValidElbowShoulder.angleTo(lastValidElbowHand)) > MAX_RATE_OF_ANGLE_CHANGE)
            {
                // Console.WriteLine("angle change too fast");
                return false;       // moving too fast
            }

            // Console.WriteLine("last frame Angle " + lastElbowShoulder.angleTo(lastElbowHand) + " last Valid Frame Angle " + lastValidElbowShoulder.angleTo(lastValidElbowHand) +
            //                             " difference " + (lastElbowShoulder.angleTo(lastElbowHand) - lastValidElbowShoulder.angleTo(lastValidElbowHand)));
            switch (gesture)
            {
                case GESTURE.SWIPE_RIGHT:
                    {

                        /*
                         *  we are getting only the magnitude of the angles here, so swipe right opposite is moving from larger angle to smaller angle
                         */

                        if (lastElbowShoulder.angleTo(lastElbowHand) - lastValidElbowShoulder.angleTo(lastValidElbowHand) <= -THRESHOLD_OPPOSITE_ANGLE)
                        {
                            // Console.WriteLine("Gesture : SWIPE RIGHT , OPPOSITE MOTION ....");
                            return false;
                        }

                    }
                    break;
                case GESTURE.SWIPE_LEFT:
                    {
                        if (lastElbowShoulder.angleTo(lastElbowHand) - lastValidElbowShoulder.angleTo(lastValidElbowHand) >= THRESHOLD_OPPOSITE_ANGLE)
                        {
                            // Console.WriteLine("Gesture : SWIPE LEFT , OPPOSITE MOTION ....");
                            return false;
                        }

                    }
                    break;
            }

            return true;
        }
Esempio n. 8
0
        private bool isFirstValidGestureFrame(GESTURE gesture , GestureDatabase gestureDatabase)
        {
            Skeleton skeleton;
            AppropriateJointInfo aptJointInfo;

            gestureDatabase.getLastRecord(out skeleton ,out aptJointInfo);

            switch(gesture)
            {
                case GESTURE.SWIPE_RIGHT:
                    {
                        HCI580_Geometry.Vector2D elbowShoulder = new HCI580_Geometry.Vector2D((aptJointInfo.shoulderRightPos.X - aptJointInfo.elbowRightPos.X),
                                                                                              (aptJointInfo.shoulderRightPos.Y - aptJointInfo.elbowRightPos.Y));

                        HCI580_Geometry.Vector2D elbowHand = new HCI580_Geometry.Vector2D((aptJointInfo.handRightPos.X - aptJointInfo.elbowRightPos.X),
                                                                                          (aptJointInfo.handRightPos.Y - aptJointInfo.elbowRightPos.Y));

                        // check if hand Y > elbow Y , hand X < elbow X and angle between elbowShoulder and elbowHand negative
                        if(aptJointInfo.handRightPos.Y > aptJointInfo.elbowRightPos.Y &&
                           aptJointInfo.handRightPos.X < aptJointInfo.elbowRightPos.X &&
                           elbowShoulder.cpsign(elbowHand) < 0)
                        {
                            return true;
                        }
                    }
                    break;

                case GESTURE.SWIPE_LEFT:
                    {
                        HCI580_Geometry.Vector2D elbowShoulder = new HCI580_Geometry.Vector2D((aptJointInfo.shoulderRightPos.X - aptJointInfo.elbowRightPos.X),
                                                                                              (aptJointInfo.shoulderRightPos.Y - aptJointInfo.elbowRightPos.Y));

                        HCI580_Geometry.Vector2D elbowHand = new HCI580_Geometry.Vector2D((aptJointInfo.handRightPos.X - aptJointInfo.elbowRightPos.X),
                                                                                          (aptJointInfo.handRightPos.Y - aptJointInfo.elbowRightPos.Y));

                        // check if hand Y > elbow Y , hand X < elbow X and angle between elbowShoulder and elbowHand negative
                        if(aptJointInfo.handRightPos.Y > aptJointInfo.elbowRightPos.Y &&
                           aptJointInfo.handRightPos.X > aptJointInfo.elbowRightPos.X &&
                           elbowShoulder.cpsign(elbowHand) < 0)
                        {
                            return true;
                        }
                    }
                    break;

            }
            return false;
        }
Esempio n. 9
0
        /*
         * doc: The function takes the first valid gesture frame ,depending upon what the gesture is, and currently added
         *      and compares the shouldercenter position , which is representative of the body , accross these frames to
         *      check for out of range body movements
         */
        private bool isBodyLinearDeflectionWithInBounds(GESTURE gesture ,  GestureDatabase gestureDatabase)
        {
            Skeleton firstValidSkeleton;
            AppropriateJointInfo firstValidAptInfo;
            Skeleton currentSkeleton;
            AppropriateJointInfo currentAptInfo;

            int indexOfFirstValidGesture = (gesture == GESTURE.SWIPE_LEFT) ?
                                            indexOfFirstValidSwipeLeftFrame :
                                            indexOfFirstValidSwipeRightFrame;

            if(indexOfFirstValidGesture < 0)
                return true;

            gestureDatabase.getLastRecord(out currentSkeleton, out currentAptInfo);                           // last added frame
            gestureDatabase.getRecord(indexOfFirstValidGesture , out firstValidSkeleton , out firstValidAptInfo);       // first valid frame

            // difference between joint positions of shouldercenter in currently added and first valid gesture frame
            return isJointDelectionValid(currentAptInfo.shoulderCenterPos, firstValidAptInfo.shoulderCenterPos);
        }
 public bool processVerticalUpGesture(GestureDatabase gestureDatabase)
 {
     return false;
 }
        private bool isIntermediaryFrameValidGestureFrame(GESTURE gesture, GestureDatabase gestureDatabase)
        {
            Skeleton currentSkeleton;
            AppropriateJointInfo currentAptJointInfo;

            gestureDatabase.getLastRecord(out currentSkeleton, out currentAptJointInfo);

            Vector2D currentElbowShoulder = new Vector2D((currentAptJointInfo.shoulderRightPos.X - currentAptJointInfo.elbowRightPos.X),
                                                                     (currentAptJointInfo.shoulderRightPos.Y - currentAptJointInfo.elbowRightPos.Y));

            Vector2D currentElbowHand = new Vector2D((currentAptJointInfo.handRightPos.X - currentAptJointInfo.elbowRightPos.X),
                                                         (currentAptJointInfo.handRightPos.Y - currentAptJointInfo.elbowRightPos.Y));

            double angle = currentElbowShoulder.angleTo(currentElbowHand);

            switch (gesture)
            {
                case GESTURE.CONST_LEFT:
                    {

                        if (currentAptJointInfo.shoulderCenterPos.Y > currentAptJointInfo.handRightPos.Y &&
                           currentAptJointInfo.shoulderCenterPos.Y > currentAptJointInfo.elbowRightPos.Y &&
                           currentAptJointInfo.handRightPos.X < currentAptJointInfo.elbowRightPos.X &&
                           currentElbowShoulder.cpsign(currentElbowHand) > 0 &&
                           angle >= CONST_LEFT_GESTURE_MIN_THETA - THRESHOLD_ANGLE_DEFLECTION &&
                           angle <= CONST_LEFT_GESTURE_MAX_THETA + THRESHOLD_ANGLE_DEFLECTION)
                        {
                            return true;
                        }

                    }
                    break;

                case GESTURE.CONST_RIGHT:
                    {
                        if (
                          currentAptJointInfo.shoulderCenterPos.Y > currentAptJointInfo.elbowRightPos.Y &&
                          currentAptJointInfo.elbowRightPos.Y > currentAptJointInfo.handRightPos.Y &&
                          currentAptJointInfo.handRightPos.X > currentAptJointInfo.elbowRightPos.X &&
                          currentElbowShoulder.cpsign(currentElbowHand) < 0 &&
                          angle >= CONST_RIGHT_GESTURE_MIN_THETA - THRESHOLD_ANGLE_DEFLECTION &&
                          angle <= CONST_RIGHT_GESTURE_MAX_THETA + THRESHOLD_ANGLE_DEFLECTION)
                        {
                            return true;
                        }
                    }
                    break;
            }

            return false;
        }
        private bool isIntermediaryCumulativeAngleDeflectionValid(GESTURE gesture ,  GestureDatabase gestureDatabase)
        {
            Skeleton firstValidSkeleton;
            AppropriateJointInfo firstValidAptJointInfo;
            Skeleton currentSkeleton;
            AppropriateJointInfo currentAptJointInfo;

            int indexOfFirstValidGestureFrame = (gesture == GESTURE.CONST_LEFT) ?
                                                 indexOfFirstValidConstLeftGestureFrame :
                                                 indexOfFirstValidConstRightGestureFrame;

            gestureDatabase.getLastRecord(out currentSkeleton , out currentAptJointInfo);
            gestureDatabase.getRecord(indexOfFirstValidGestureFrame, out firstValidSkeleton , out firstValidAptJointInfo);

            Vector2D currentElbowShoulder = new Vector2D((currentAptJointInfo.shoulderRightPos.X - currentAptJointInfo.elbowRightPos.X),
                                                         (currentAptJointInfo.shoulderRightPos.Y - currentAptJointInfo.elbowRightPos.Y));
            Vector2D currentElbowHand = new Vector2D((currentAptJointInfo.handRightPos.X - currentAptJointInfo.elbowRightPos.X),
                                                         (currentAptJointInfo.handRightPos.Y - currentAptJointInfo.elbowRightPos.Y));

            Vector2D firstElbowShoulder = new Vector2D((firstValidAptJointInfo.shoulderRightPos.X - firstValidAptJointInfo.elbowRightPos.X),
                                                         (firstValidAptJointInfo.shoulderRightPos.Y - firstValidAptJointInfo.elbowRightPos.Y));
            Vector2D firstElbowHand = new Vector2D((firstValidAptJointInfo.handRightPos.X - firstValidAptJointInfo.elbowRightPos.X),
                                                         (firstValidAptJointInfo.handRightPos.Y - firstValidAptJointInfo.elbowRightPos.Y));

            double angularDeflection = Math.Abs(currentElbowShoulder.angleTo(currentElbowHand) - firstElbowShoulder.angleTo(firstElbowHand));

            if (angularDeflection <= THRESHOLD_ANGLE_DEFLECTION)
                return true;

            return false;
        }
        private bool isHandAngleDeflectionWithInBounds(GESTURE gesture, GestureDatabase gestureDatabase)
        {
            Skeleton skeleton;
            AppropriateJointInfo aptJoint;

            switch (gesture)
            {
                case GESTURE.CONST_LEFT:
                    {
                        gestureDatabase.getLastRecord(out skeleton, out aptJoint);
                        Vector2D elbowShoulder = new Vector2D(aptJoint.shoulderRightPos.X - aptJoint.elbowRightPos.X, aptJoint.shoulderRightPos.Y - aptJoint.elbowRightPos.Y);
                        Vector2D elbowHand = new Vector2D(aptJoint.handRightPos.X - aptJoint.elbowRightPos.X, aptJoint.handRightPos.Y - aptJoint.elbowRightPos.Y);

                        if (elbowShoulder.cpsign(elbowHand) > 0 &&
                            elbowShoulder.angleTo(elbowHand) >= CONST_LEFT_GESTURE_MIN_THETA - THRESHOLD_ANGLE_DEFLECTION &&
                            elbowShoulder.angleTo(elbowHand) <= CONST_LEFT_GESTURE_MAX_THETA + THRESHOLD_ANGLE_DEFLECTION)
                        {
                            return true;
                        }
                        break;
                    }
                case GESTURE.CONST_RIGHT:
                    {
                        gestureDatabase.getLastRecord(out skeleton, out aptJoint);
                        Vector2D elbowShoulder = new Vector2D(aptJoint.shoulderRightPos.X - aptJoint.elbowRightPos.X, aptJoint.shoulderRightPos.Y - aptJoint.elbowRightPos.Y);
                        Vector2D elbowHand = new Vector2D(aptJoint.handRightPos.X - aptJoint.elbowRightPos.X, aptJoint.handRightPos.Y - aptJoint.elbowRightPos.Y);

                        if (elbowShoulder.cpsign(elbowHand) < 0 &&
                            elbowShoulder.angleTo(elbowHand) >= CONST_RIGHT_GESTURE_MIN_THETA - THRESHOLD_ANGLE_DEFLECTION &&
                            elbowShoulder.angleTo(elbowHand) <= CONST_RIGHT_GESTURE_MAX_THETA + THRESHOLD_ANGLE_DEFLECTION)
                        {
                            return true;
                        }
                        break;
                    }
            }
            return false;
        }
 private bool isFirstValidGestureFrame(GESTURE gesture, GestureDatabase gestureDatabase)
 {
     return isIntermediaryFrameValidGestureFrame(gesture , gestureDatabase);
 }
        private bool isBodyLinearDeflectionsWithInBounds(GESTURE gesture , GestureDatabase gestureDatabase)
        {
            if(gesture == GESTURE.CONST_LEFT)
                if (indexOfFirstValidConstLeftGestureFrame < 0)
                    return true;                        // this is the start of the new Gesture, first frame of the new gesture

            if (gesture == GESTURE.CONST_RIGHT)
                if (indexOfFirstValidConstRightGestureFrame < 0)
                    return true;                        // this is the start of the new Gesture, first frame of the new gesture
            int indexOfFirstValidGestureFrame = (gesture == GESTURE.CONST_LEFT) ? indexOfFirstValidConstLeftGestureFrame :
                                                                                  indexOfFirstValidConstRightGestureFrame;

            Skeleton lastValidSkeleton;
            AppropriateJointInfo lastAptInfo;

            Skeleton firstValidSkeleton;
            AppropriateJointInfo firstAptInfo;

            gestureDatabase.getRecord(gestureDatabase.getTotalSize() - 1, out lastValidSkeleton, out lastAptInfo);
            gestureDatabase.getRecord(indexOfFirstValidGestureFrame, out firstValidSkeleton, out firstAptInfo);

            return (isPointWithInThreshold(lastAptInfo.shoulderCenterPos, firstAptInfo.shoulderCenterPos));
        }