예제 #1
0
        //returns vector one minus vector two
        public static myCoord subtract(myCoord one, myCoord two)
        {
            myCoord toReturn = new myCoord();

            toReturn.X = one.X - two.X;
            toReturn.Y = one.Y - two.Y;
            toReturn.Z = one.Z - two.Z;
            return(toReturn);
        }
        private float fastDistanceFromPlane(myCoord point)
        {
            //source: http://mathworld.wolfram.com/Point-PlaneDistance.html

            //get a vector that represents moving from the point to the top left of the screen
            myCoord vectorFromPointToTopLeft = myCoord.subtract(point, KinectMainController.topLeft);

            return(myCoord.dotProduct(normalisedPlanePerpendicular, vectorFromPointToTopLeft));
        }
        private float fastDistanceFromPlane(myCoord point)
        {
            //source: http://mathworld.wolfram.com/Point-PlaneDistance.html

            //get a vector that represents moving from the point to the top left of the screen
            myCoord vectorFromPointToTopLeft = myCoord.subtract(point, KinectMainController.topLeft);

            return myCoord.dotProduct(normalisedPlanePerpendicular, vectorFromPointToTopLeft);
        }
예제 #4
0
        //returns the scalar multiple of a given vector, without altering the original
        public static myCoord multByScalar(myCoord vector, float scalar)
        {
            myCoord toReturn = new myCoord();

            toReturn.X = vector.X * scalar;
            toReturn.Y = vector.Y * scalar;
            toReturn.Z = vector.Z * scalar;

            return(toReturn);
        }
        //returns the y coordinate of the point on the plane closest to this point
        private float yCoordPerpFromPlane(myCoord point)
        {
            //source: http://mathworld.wolfram.com/Point-PlaneDistance.html

            myCoord verticalEdgeDirection = myCoord.subtract(KinectMainController.topLeft, KinectMainController.bottomLeft);

            myCoord vectorFromPointToTopLeft = myCoord.subtract(KinectMainController.topLeft, point);

            return(myCoord.dotProduct(verticalEdgeDirection, vectorFromPointToTopLeft) / (float)Math.Pow(myCoord.norm(verticalEdgeDirection), 2));
        }
예제 #6
0
        private myCoord getCorner()
        {
            const float   eps    = 0.00006f;                             //epsilon value, dictates precision for the variance
            myCoord       sample = new myCoord();                        //sample data we get after each time span
            Queue <float> xQueue = new Queue <float>(10);                //queues for the x, y, z values
            Queue <float> yQueue = new Queue <float>(10);                //we get data every 0.2 seconds, and stop when we detect that the
            Queue <float> zQueue = new Queue <float>(10);                //hand has stayed still for 2 seconds, hence analyse the last 10 values

            System.DateTime t1   = System.DateTime.Now;                  //current time
            System.TimeSpan span = new System.TimeSpan(0, 0, 0, 0, 200); //time span of 0.2 seconds between each sampling of the position
            System.DateTime t3   = new System.DateTime();                //time at which we have to get the new sample

            //fill the queues with the initial 10 samples
            while (xQueue.Count < 10)
            {
                t3 = t1.Add(span);                                                      //when we get the next round of data
                xQueue.Enqueue(xCoord); yQueue.Enqueue(yCoord); zQueue.Enqueue(zCoord); //get current round of data

                //wait until next round
                while (t1 < t3)
                {
                    t1 = System.DateTime.Now;
                }
            }

            //compute the initial variances of position data
            float xVar = Variance(xQueue);
            float yVar = Variance(yQueue);
            float zVar = Variance(zQueue);

            //while the variances are to high, meaning the hand isn't still, keep tracking the hand
            while ((xVar > eps | yVar > eps | zVar > eps) || (xQueue.Average() == 0 && yQueue.Average() == 0 && zQueue.Average() == 0))
            {
                t3 = t1.Add(span);                                                         //when we get next round of data

                xQueue.Dequeue(); yQueue.Dequeue(); zQueue.Dequeue();                      //discard old data
                xQueue.Enqueue(xCoord); yQueue.Enqueue(yCoord); zQueue.Enqueue(zCoord);    //get current round
                xVar = Variance(xQueue); yVar = Variance(yQueue); zVar = Variance(zQueue); //compute new variance

                //wait until next round
                while (t1 < t3)
                {
                    t1 = System.DateTime.Now;
                }
            }

            //when the hand hasn't moved return it's position, averaging over the last 10 positions
            sample.X = xQueue.Average();
            sample.Y = yQueue.Average();
            sample.Z = zQueue.Average();

            Console.Beep();     //give an audio confirmation to the user
            return(sample);
        }
예제 #7
0
        //returns the cross product of vector one and vector two
        public static myCoord crossProduct(myCoord one, myCoord two)
        {
            //computed by definition of cross product
            myCoord answer = new myCoord();

            answer.X = one.Y * two.Z - one.Z * two.Y;
            answer.Y = one.Z * two.X - one.X * two.Z;
            answer.Z = one.X * two.Y - one.Y - two.X;

            return(answer);
        }
예제 #8
0
        //returns the distance of 'point' from the plane defined by the points planeOne, planeTwo, and planeThree. May be negative.
        public static float distanceFromPlane(myCoord planeOne, myCoord planeTwo, myCoord planeThree, myCoord point)
        {
            myCoord vectorFromPointToPlaneOne = subtract(point, planeOne);

            //compute plane perpendicular
            myCoord normalisedPlanePerpendicular = crossProduct(subtract(planeTwo, planeOne), subtract(planeThree, planeOne));

            //normalise it
            normalisedPlanePerpendicular = multByScalar(normalisedPlanePerpendicular, 1 / norm(normalisedPlanePerpendicular));


            //dot it with the vector from planeOne to point
            return(myCoord.dotProduct(normalisedPlanePerpendicular, vectorFromPointToPlaneOne));
        }
        public void justCalibrated()
        {
            //to get the normalised plane perpendicular (for caching):
            //source: http://mathworld.wolfram.com/Point-PlaneDistance.html

            //get a vector parallel to the top and side edges of the screen
            myCoord horizontalEdgeDirection = myCoord.subtract(KinectMainController.topRight, KinectMainController.topLeft);
            myCoord verticalEdgeDirection = myCoord.subtract(KinectMainController.bottomLeft, KinectMainController.topLeft);

            //get a vector perpendicular to the plane (not yet normalised)
            normalisedPlanePerpendicular = myCoord.crossProduct(horizontalEdgeDirection, verticalEdgeDirection);

            //normalise it - will fail if two points on the screen are in the same place (makes the planePerpendicular 0) - TODO I have NOT guarded against this
            normalisedPlanePerpendicular = myCoord.multByScalar(normalisedPlanePerpendicular, 1 / myCoord.norm(normalisedPlanePerpendicular));
        }
        public void justCalibrated()
        {
            //to get the normalised plane perpendicular (for caching):
            //source: http://mathworld.wolfram.com/Point-PlaneDistance.html

            //get a vector parallel to the top and side edges of the screen
            myCoord horizontalEdgeDirection = myCoord.subtract(KinectMainController.topRight, KinectMainController.topLeft);
            myCoord verticalEdgeDirection   = myCoord.subtract(KinectMainController.bottomLeft, KinectMainController.topLeft);


            //get a vector perpendicular to the plane (not yet normalised)
            normalisedPlanePerpendicular = myCoord.crossProduct(horizontalEdgeDirection, verticalEdgeDirection);


            //normalise it - will fail if two points on the screen are in the same place (makes the planePerpendicular 0) - TODO I have NOT guarded against this
            normalisedPlanePerpendicular = myCoord.multByScalar(normalisedPlanePerpendicular, 1 / myCoord.norm(normalisedPlanePerpendicular));
        }
예제 #11
0
 //returns one 'dotproduct' two.
 public static float dotProduct(myCoord one, myCoord two)
 {
     return one.X * two.X + one.Y * two.Y + one.Z * two.Z;
 }
예제 #12
0
 //returns one 'dotproduct' two.
 public static float dotProduct(myCoord one, myCoord two)
 {
     return(one.X * two.X + one.Y * two.Y + one.Z * two.Z);
 }
예제 #13
0
 //returns the euclidean norm of a 3d vector
 public static float norm(myCoord vector)
 {
     return((float)Math.Sqrt(vector.X * vector.X + vector.Y * vector.Y + vector.Z * vector.Z));
 }
        void _sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
        {
            if (!KinectMainController.isCalibrated || !KinectMainController.doMouseInput)
            {
                return;
            }

            Skeleton first = Kinetique.Calibrator.GetFirstSkeleton(e);

            if (first == null)
            {
                return;
            }

            var rightHand = first.Joints[JointType.HandRight];

            if (rightHand.TrackingState != JointTrackingState.Tracked)
            {
                //Don't have a good read on the joints so we cannot process gestures
                return;
            }
            myCoord handLeft = new myCoord();

            handLeft.X = first.Joints[JointType.HandLeft].Position.X;
            handLeft.Y = first.Joints[JointType.HandLeft].Position.Y;
            handLeft.Z = first.Joints[JointType.HandLeft].Position.Z;

            myCoord handRight = new myCoord();

            handRight.X = first.Joints[JointType.HandRight].Position.X;
            handRight.Y = first.Joints[JointType.HandRight].Position.Y;
            handRight.Z = first.Joints[JointType.HandRight].Position.Z;

            //distance in metres from screen
            float handRightDistance = Math.Abs(fastDistanceFromPlane(handRight));

            //scalars between 0 and 1 - 0 is the left, and the top
            float handRightX = xCoordPerpFromPlane(handRight);
            float handRightY = yCoordPerpFromPlane(handRight);

            outputToListener(handRightX, handRightY, handRightDistance, 0);



            ////distance in metres from screen
            float handLeftDistance = Math.Abs(fastDistanceFromPlane(handLeft));

            //scalars between 0 and 1 - 0 is the left, and the top
            float handLeftX = xCoordPerpFromPlane(handLeft);
            float handLeftY = yCoordPerpFromPlane(handLeft);

            if (handLeftDistance < metresFromPlaneToDraw && !handDown[1])
            {
                handDown[1] = true;
                if (!handDown[0])
                {
                    listener.MouseDown(mouseX, mouseY, 1);
                    listener.MouseUp(mouseX, mouseY, 1);
                }
            }
            else if (handLeftDistance > metresFromPlaneToDraw && handDown[1])
            {
                handDown[1] = false;
            }

            if (handRightDistance > 1 && handLeftDistance > 1)
            {
                KinectMainController.doGestureRecognition = false;
            }
            else
            {
                KinectMainController.doGestureRecognition = true;
            }
        }
        //returns the y coordinate of the point on the plane closest to this point
        private float yCoordPerpFromPlane(myCoord point)
        {
            //source: http://mathworld.wolfram.com/Point-PlaneDistance.html

            myCoord verticalEdgeDirection = myCoord.subtract(KinectMainController.topLeft, KinectMainController.bottomLeft);

            myCoord vectorFromPointToTopLeft = myCoord.subtract(KinectMainController.topLeft, point);

            return myCoord.dotProduct(verticalEdgeDirection, vectorFromPointToTopLeft) / (float) Math.Pow(myCoord.norm(verticalEdgeDirection), 2);
        }
        void _sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
        {
            if (!KinectMainController.isCalibrated || !KinectMainController.doMouseInput)
                return;

            Skeleton first = Kinetique.Calibrator.GetFirstSkeleton(e);

            if (first == null)
            {
                return;
            }

            var rightHand = first.Joints[JointType.HandRight];

            if (rightHand.TrackingState != JointTrackingState.Tracked)
            {
                //Don't have a good read on the joints so we cannot process gestures
                return;
            }
            myCoord handLeft = new myCoord();

            handLeft.X = first.Joints[JointType.HandLeft].Position.X;
            handLeft.Y = first.Joints[JointType.HandLeft].Position.Y;
            handLeft.Z = first.Joints[JointType.HandLeft].Position.Z;

            myCoord handRight = new myCoord();

            handRight.X = first.Joints[JointType.HandRight].Position.X;
            handRight.Y = first.Joints[JointType.HandRight].Position.Y;
            handRight.Z = first.Joints[JointType.HandRight].Position.Z;

            //distance in metres from screen
            float handRightDistance = Math.Abs(fastDistanceFromPlane(handRight));

            //scalars between 0 and 1 - 0 is the left, and the top
            float handRightX = xCoordPerpFromPlane(handRight);
            float handRightY = yCoordPerpFromPlane(handRight);

            outputToListener(handRightX, handRightY, handRightDistance, 0);

            ////distance in metres from screen
            float handLeftDistance = Math.Abs(fastDistanceFromPlane(handLeft));

            //scalars between 0 and 1 - 0 is the left, and the top
            float handLeftX = xCoordPerpFromPlane(handLeft);
            float handLeftY = yCoordPerpFromPlane(handLeft);

            if (handLeftDistance < metresFromPlaneToDraw && !handDown[1])
            {
                handDown[1] = true;
                if (!handDown[0])
                {
                    listener.MouseDown(mouseX, mouseY, 1);
                    listener.MouseUp(mouseX, mouseY, 1);
                }
            }
            else if (handLeftDistance > metresFromPlaneToDraw && handDown[1])
                handDown[1] = false;

            if (handRightDistance > 1 && handLeftDistance > 1)
                KinectMainController.doGestureRecognition = false;
            else KinectMainController.doGestureRecognition = true;
        }
예제 #17
0
 //returns vector one minus vector two
 public static myCoord subtract(myCoord one, myCoord two)
 {
     myCoord toReturn = new myCoord();
     toReturn.X = one.X - two.X;
     toReturn.Y = one.Y - two.Y;
     toReturn.Z = one.Z - two.Z;
     return toReturn;
 }
예제 #18
0
 //returns the euclidean norm of a 3d vector
 public static float norm(myCoord vector)
 {
     return (float)Math.Sqrt(vector.X * vector.X + vector.Y * vector.Y + vector.Z * vector.Z);
 }
예제 #19
0
        //returns the scalar multiple of a given vector, without altering the original
        public static myCoord multByScalar(myCoord vector, float scalar)
        {
            myCoord toReturn = new myCoord();

            toReturn.X = vector.X * scalar;
            toReturn.Y = vector.Y * scalar;
            toReturn.Z = vector.Z * scalar;

            return toReturn;
        }
예제 #20
0
        //returns the distance of 'point' from the plane defined by the points planeOne, planeTwo, and planeThree. May be negative.
        public static float distanceFromPlane(myCoord planeOne, myCoord planeTwo, myCoord planeThree, myCoord point)
        {
            myCoord vectorFromPointToPlaneOne = subtract(point, planeOne);

            //compute plane perpendicular
            myCoord normalisedPlanePerpendicular = crossProduct(subtract(planeTwo, planeOne), subtract(planeThree, planeOne));
            //normalise it
            normalisedPlanePerpendicular = multByScalar(normalisedPlanePerpendicular, 1 / norm(normalisedPlanePerpendicular));

            //dot it with the vector from planeOne to point
            return myCoord.dotProduct(normalisedPlanePerpendicular, vectorFromPointToPlaneOne);
        }
예제 #21
0
        //returns the cross product of vector one and vector two
        public static myCoord crossProduct(myCoord one, myCoord two)
        {
            //computed by definition of cross product
            myCoord answer = new myCoord();
            answer.X = one.Y * two.Z - one.Z * two.Y;
            answer.Y = one.Z * two.X - one.X * two.Z;
            answer.Z = one.X * two.Y - one.Y - two.X;

            return answer;
        }
예제 #22
0
        private myCoord getCorner()
        {
            const float eps = 0.00006f;                     //epsilon value, dictates precision for the variance
            myCoord sample = new myCoord();                 //sample data we get after each time span
            Queue<float> xQueue = new Queue<float>(10);     //queues for the x, y, z values
            Queue<float> yQueue = new Queue<float>(10);     //we get data every 0.2 seconds, and stop when we detect that the
            Queue<float> zQueue = new Queue<float>(10);     //hand has stayed still for 2 seconds, hence analyse the last 10 values

            System.DateTime t1 = System.DateTime.Now;       //current time
            System.TimeSpan span = new System.TimeSpan(0, 0, 0, 0, 200);  //time span of 0.2 seconds between each sampling of the position
            System.DateTime t3 = new System.DateTime();     //time at which we have to get the new sample

            //fill the queues with the initial 10 samples
            while (xQueue.Count < 10)
            {
                t3 = t1.Add(span);      //when we get the next round of data
                xQueue.Enqueue(xCoord); yQueue.Enqueue(yCoord); zQueue.Enqueue(zCoord); //get current round of data

                //wait until next round
                while (t1 < t3)
                {
                    t1 = System.DateTime.Now;
                }
            }

            //compute the initial variances of position data
            float xVar = Variance(xQueue);
            float yVar = Variance(yQueue);
            float zVar = Variance(zQueue);

            //while the variances are to high, meaning the hand isn't still, keep tracking the hand
            while ((xVar > eps | yVar > eps | zVar > eps) || (xQueue.Average() == 0 && yQueue.Average() == 0 && zQueue.Average() == 0))
            {
                t3 = t1.Add(span);      //when we get next round of data

                xQueue.Dequeue(); yQueue.Dequeue(); zQueue.Dequeue();                       //discard old data
                xQueue.Enqueue(xCoord); yQueue.Enqueue(yCoord); zQueue.Enqueue(zCoord);     //get current round
                xVar = Variance(xQueue); yVar = Variance(yQueue); zVar = Variance(zQueue);  //compute new variance

                //wait until next round
                while (t1 < t3)
                {
                    t1 = System.DateTime.Now;
                }
            }

            //when the hand hasn't moved return it's position, averaging over the last 10 positions
            sample.X = xQueue.Average();
            sample.Y = yQueue.Average();
            sample.Z = zQueue.Average();

            Console.Beep();     //give an audio confirmation to the user
            return sample;
        }