public double angleTo(Vector2D vec) { double length = vectorLength() * vec.vectorLength(); if (length == 0) return 0; return (180 / Math.PI) * Math.Acos(dotp(vec) / length); }
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; }
public double dotp(Vector2D vec) { return X * vec.X + Y * vec.Y; }
public int cpsign(Vector2D vec) { return ((X * vec.Y - Y * vec.X) > 0) ? 1 : ((X * vec.Y - Y * vec.X) < 0) ? -1 : 0; }
public Vector2D(Vector2D vec) { this.X = vec.X; this.Y = vec.Y; }