public Hand() { palm = new PointFT(-1, -1); fingertips = new List<PointFT>(5); fingertips3D = new List<Vector3FT>(5); contour = new List<PointFT>(2000); inside = new List<PointFT>(6000); leftUpperCorner = new PointFT(int.MaxValue, int.MaxValue); rightDownCorner = new PointFT(int.MinValue, int.MinValue); }
/// <summary> /// Divides the source point by an scalar. /// </summary> /// <param name="point1">Source point.</param> /// <param name="value">The divisor.</param> /// <returns>Returns the division.</returns> public static PointFT divide(PointFT point1, int value) { PointFT sol = new PointFT(); sol.X = point1.X / value; sol.Y = point1.Y / value; return sol; }
/// <summary> /// Divides two points. /// </summary> /// <param name="point1">The dividend.</param> /// <param name="point2">The divisor.</param> /// <returns>Returns the division.</returns> public static PointFT divide(PointFT point1, PointFT point2) { PointFT sol = new PointFT(); sol.X = point1.X / point2.X; sol.Y = point1.Y / point2.Y; return sol; }
/// <summary> /// Calculates the Euclidean distance between two points. /// </summary> /// <param name="point1">Source point.</param> /// <param name="point2">Source point.</param> /// <returns>Returns the distance between the points squared.</returns> public static float distanceEuclideanSquared(PointFT point1, PointFT point2) { return (point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y); }
private void updatePictureBox() { //slide if (kinectController.hands.Count > 0) { int numberFinger1 = kinectController.hands[0].fingertips.Count; if (numberFinger1 == 2) { if (initTimeToSlide) { initPointSlide1 = new PointFT(kinectController.hands[0].fingertips[0].X, kinectController.hands[0].fingertips[0].Y); initPointSlide2 = new PointFT(kinectController.hands[0].fingertips[1].X, kinectController.hands[0].fingertips[1].Y); distanceBetweenFingers = PointFT.distanceEuclidean(initPointSlide1, initPointSlide2); initTimeToSlide = false; } else { checkerSlide++; if (checkerSlide >= 3) { PointFT curPoint = new PointFT(kinectController.hands[0].fingertips[0].X, kinectController.hands[0].fingertips[0].Y); PointFT curPoint2 = new PointFT(kinectController.hands[0].fingertips[1].X, kinectController.hands[0].fingertips[1].Y); float distanceBetweenStates = PointFT.distanceEuclidean(curPoint, initPointSlide1); float disBwFingers = PointFT.distanceEuclidean(curPoint, curPoint2); if (distanceBetweenStates >= 40 && disBwFingers >= distanceBetweenFingers - 10 && disBwFingers <= distanceBetweenFingers + 10 && curPoint.X < initPointSlide1.X) { string[] files = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.jpg", SearchOption.AllDirectories); image = Image.FromFile(files[index]); imageBitmap = new Bitmap(image, returnWidth(image), returnHeight(image)); mImage.Image = imageBitmap; index++; if (index==files.Length) { index = 0; } } initTimeToSlide = true; checkerSlide = 0; } } } else { checkerSlide = 0; } } //zoom if (kinectController.hands.Count > 1) { int mNumberFinger1 = kinectController.hands[0].fingertips.Count; int mNumberFinger2 = kinectController.hands[1].fingertips.Count; if (mNumberFinger1 == 1 && mNumberFinger2 == 1) { checkerZoom++; if (checkerZoom >= 3) { checkerZoom = 0; double curDistance = Math.Sqrt(Math.Pow(kinectController.hands[0].fingertips[0].X - kinectController.hands[1].fingertips[0].X, 2) + Math.Pow(kinectController.hands[0].fingertips[0].Y - kinectController.hands[1].fingertips[0].Y, 2) ); if (initTimeToZoom) { initDistance = (float)(curDistance); if (initDistance > 60 && initDistance < 70) { initTimeToZoom = false; } } else { float ratio = (float)(curDistance * 1.0f / initDistance); int widthTemp = (int)(returnWidth(image) * ratio); int heightTemp = (int)(returnHeight(image) * ratio); if (widthTemp <= initSize.Width || heightTemp <= initSize.Height) { imageBitmap = new Bitmap(image, new Size(widthTemp, heightTemp)); mImage.Image = imageBitmap; } mRatioValue.Text = ratio.ToString(); } } } else { checkerSlide = 0; checkerZoom = 0; mRatioValue.Text = ""; } } }
/// <summary> /// Subtracts a scalar to all the coordinates of the source point. /// </summary> /// <param name="point1">Source point.</param> /// <param name="value">The scalar to substract.</param> /// <returns>Returs the difference.</returns> public static PointFT subtract(PointFT point1, int value) { PointFT sol = new PointFT(); sol.X = point1.X - value; sol.Y = point1.Y - value; return sol; }
/// <summary> /// Multiplies the source point by a scalar. /// </summary> /// <param name="point1">Source point.</param> /// <param name="value">The factor.</param> /// <returns>Returns the product.</returns> public static PointFT multiply(PointFT point1,int value) { PointFT sol = new PointFT(); sol.X = point1.X * value; sol.Y = point1.Y * value; return sol; }
/// <summary> /// Multiplies two points. /// </summary> /// <param name="point1">Source point.</param> /// <param name="point2">Source point.</param> /// <returns>Returns the product.</returns> public static PointFT multiply(PointFT point1, PointFT point2) { PointFT sol = new PointFT(); sol.X = point1.X * point2.X; sol.Y = point1.Y * point2.Y; return sol; }
/// <summary> /// Adds two points. /// </summary> /// <param name="point1">Source point.</param> /// <param name="point2">Source point.</param> /// <returns>Returns the sum.</returns> public static PointFT add(PointFT point1, PointFT point2) { PointFT sol = new PointFT(); sol.X = point1.X + point2.X; sol.Y = point1.Y + point2.Y; return sol; }
/// <summary> /// Subtracts a scalar to all the coordinates of the source point. /// </summary> /// <param name="point1">Source point.</param> /// <param name="value">The scalar to substract.</param> /// <returns>Returs the difference.</returns> public static PointFT operator -(PointFT point1, int value) { PointFT sol = new PointFT(); sol.X = point1.X - value; sol.Y = point1.Y - value; return sol; }
// Calculate the contour box of the hand if it possible public bool calculateContainerBox(float reduction = 0) { if (contour != null && contour.Count > 0) { for (int j = 0; j < contour.Count; ++j) { if (leftUpperCorner.X > contour[j].X) leftUpperCorner.X = contour[j].X; if (rightDownCorner.X < contour[j].X) rightDownCorner.X = contour[j].X; if (leftUpperCorner.Y > contour[j].Y) leftUpperCorner.Y = contour[j].Y; if (rightDownCorner.Y < contour[j].Y) rightDownCorner.Y = contour[j].Y; } int incX = (int)((rightDownCorner.X - leftUpperCorner.X) * (reduction / 2)); int incY = (int)((rightDownCorner.Y - leftUpperCorner.Y) * (reduction / 2)); PointFT inc = new PointFT(incX, incY); leftUpperCorner = leftUpperCorner + inc; rightDownCorner = rightDownCorner + inc; return true; } else { return false; } }
// Normalize in the interval [-1, 1] the given 3D point. // The Z value is in the inverval [-1, 0], being 0 the closest distance. private Vector3FT transformTo3DCoord(PointFT p, int width, int height, int distance) { Vector3FT v = new Vector3FT(); v.X = p.Y / (width * 1.0f) * 2 - 1; v.Y = (1 - p.X / (height * 1.0f)) * 2 - 1; v.Z = (distance - 400) / -7600.0f; return v; }
// Check if a point is inside the hand countour box public bool isPointInsideContainerBox(PointFT p) { if (p.X < rightDownCorner.X && p.X > leftUpperCorner.X && p.Y > leftUpperCorner.Y && p.Y < rightDownCorner.Y) { return true; } else { return false; } }
public bool isCircleInsideContainerBox(PointFT p, float r) { if (leftUpperCorner.X > p.X - r) { return false; } if (rightDownCorner.X < p.X + r) { return false; } if (leftUpperCorner.Y > p.Y - r) { return false; } if (rightDownCorner.Y < p.Y + r) { return false; } return true; }
/// <summary> /// Calculates the dot product of two points. Returns a floating point value between -1 and 1. /// </summary> /// <param name="point1">Source point.</param> /// <param name="point2">Source point.</param> /// <returns>Returns the dot product of the source points.</returns> public static float dot(PointFT point1, PointFT point2) { return (point1.X * point2.X + point1.Y * point2.Y) / (length(point1) * length(point2)); }
/// <summary> /// Adds a scalar to all the coordinates of the source point. /// </summary> /// <param name="point1">Source point.</param> /// <param name="value">The scalar to add.</param> /// <returns>Returs the sum.</returns> public static PointFT add(PointFT point1, int value) { PointFT sol = new PointFT(); sol.X = point1.X + value; sol.Y = point1.Y + value; return sol; }
/// <summary> /// Returns the length of the source point. /// </summary> /// <returns>The length of the point.</returns> public static float length(PointFT point1) { return (float)Math.Sqrt(point1.X * point1.X + point1.Y * point1.Y); }
/// <summary> /// Calculates the smaller angle between two points. /// </summary> /// <param name="point1">Source point.</param> /// <param name="point2">Source point.</param> /// <returns>Returns the angle in radians.</returns> public static float angle(PointFT point1, PointFT point2) { return (float)Math.Acos((point1.X * point2.X + point1.Y * point2.Y) / (length(point1) * length(point2))); }
/// <summary> /// Copy and create a new instance of PointFT. /// </summary> /// <param name="other">The PointFT to copy.</param> public PointFT(PointFT other) { this.X = other.X; this.Y = other.Y; }
/// <summary> /// Calculate the number of points you have to cross to go from one point to another. /// </summary> /// <param name="point1">Source point.</param> /// <param name="point2">Source point.</param> /// <returns>Returns the distance between the points.</returns> public static int distance(PointFT point1, PointFT point2) { return Math.Abs(point1.X - point2.X) + Math.Abs(point1.Y - point2.Y); }
/// <summary> /// Subtracts two points. /// </summary> /// <param name="point1">Minuend point.</param> /// <param name="point2">Subtrahend point.</param> /// <returns>Returns the difference .</returns> public static PointFT subtract(PointFT point1, PointFT point2) { PointFT sol = new PointFT(); sol.X = point1.X - point2.X; sol.Y = point1.Y - point2.Y; return sol; }
/// <summary> /// Calculates the Euclidean distance between two points. /// </summary> /// <param name="point1">Source point.</param> /// <param name="point2">Source point.</param> /// <returns>Returns the distance between the points.</returns> public static float distanceEuclidean(PointFT point1, PointFT point2) { return (float)Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y)); }
/// <summary> /// Multiplies two points. /// </summary> /// <param name="point1">Source point.</param> /// <param name="point2">Source point.</param> /// <returns>Returns the product.</returns> public static PointFT operator *(PointFT point1, PointFT point2) { PointFT sol = new PointFT(); sol.X = point1.X * point2.X; sol.Y = point1.Y * point2.Y; return sol; }
/* * This function calcute the border of a closed figure starting in one of the contour points. * The turtle algorithm is used. */ private List<PointFT> CalculateFrontier(ref bool[][] valid, PointFT start, ref bool[][] contour) { List<PointFT> list = new List<PointFT>(); PointFT last = new PointFT(-1, -1); PointFT current = new PointFT(start); int dir = 0; do { if (valid[current.X][current.Y]) { dir = (dir + 1) % 4; if (current != last) { list.Add(new PointFT(current.X, current.Y)); last = new PointFT(current); contour[current.X][current.Y] = false; } } else { dir = (dir + 4 - 1) % 4; } switch (dir) { case 0: current.X += 1; break; // Down case 1: current.Y += 1; break; // Right case 2: current.X -= 1; break; // Up case 3: current.Y -= 1; break; // Left } } while (current != start); return list; }