private void varInitialization() { currentPoint = new TwoDPoint(0, 0); startPoint = new TwoDPoint(0, 0); currentPointList = new List <TwoDPoint>(); currentPointList.Add(new TwoDPoint(0, 0)); reducedPoints = new TwoDPoint[pointsPerGesture]; for (int i = 0; i < pointsPerGesture; i++) { reducedPoints[i] = new TwoDPoint(0, 0); } gestureStarted = false; gestureComplete = false; inputReady = false; currentGesture = new DrawnGesture("currentGesture", pointsPerGesture); }
//*************************************** // AverageDistanceWithAnomalies // // use: calculates the average difference between // the points of two gestures but weighing // those which deviate significantly by // multiplying them // Both the tightness of this and the factor // of multiplication are customizable // above // // param: playerGesture: first to be compared // template: gesture to be compared against // // return: returns float value of the average distance // between points of two parameter gestures // with weights private float AverageDifferenceWithAnomalies(DrawnGesture playerGesture, DrawnGesture template) { int numPoints = playerGesture.GetNumPoints(); if (numPoints != template.GetNumPoints()) { Debug.Log("Number of points differs from templates"); return(-1f); } float totalDifference = 0; float[] sampleDifferences = new float[numPoints]; float[] sampleDeviations = new float[numPoints]; float standardDev = 0; for (int i = 0; i < numPoints; i++) { float thisDistance = PointDistance(playerGesture.GetPoints()[i], template.GetPoints()[i]); sampleDifferences[i] = thisDistance; totalDifference += thisDistance; } float average = totalDifference / numPoints; for (int i = 0; i < numPoints; i++) { sampleDeviations[i] = Math.Abs(sampleDifferences[i] - average); standardDev += sampleDifferences[i]; } standardDev = standardDev / numPoints; for (int i = 0; i < numPoints; i++) { if (Math.Abs(sampleDeviations[i]) > devTightness * standardDev) { totalDifference -= sampleDifferences[i]; totalDifference += anomaliesFactor * sampleDifferences[i]; } } average = totalDifference / numPoints; return(average); }
//*************************************** // MapPoints // // use: maps the list of recorded points to a desired // number of points by calculating an even distance // between such a number of points and interpolating // when that distance is reached upon traversal of the // list // Called after scaling on every gesture // // param: gesture: the object to store the new array private void MapPoints(DrawnGesture gesture) { reducedPoints[0].SetX(currentPointList[0].GetX()); reducedPoints[0].SetY(currentPointList[0].GetY()); int newIndex = 1; float totalDistance = TotalDistance(); float coveredDistance = 0; float thisDistance = 0; float idealInterval = totalDistance / pointsPerGesture; for (int i = 0; i < currentPointList.Count - 1; i++) { thisDistance = PointDistance(currentPointList[i], currentPointList[i + 1]); bool passedIdeal = (coveredDistance + thisDistance) >= idealInterval; if (passedIdeal) { TwoDPoint reference = currentPointList[i]; while (passedIdeal && newIndex < reducedPoints.Length) { float percentNeeded = (idealInterval - coveredDistance) / thisDistance; if (percentNeeded > 1f) { percentNeeded = 1f; } if (percentNeeded < 0f) { percentNeeded = 0f; } float new_x = (((1f - percentNeeded) * reference.GetX()) + (percentNeeded * currentPointList[i + 1].GetX())); float new_y = (((1f - percentNeeded) * reference.GetY()) + (percentNeeded * currentPointList[i + 1].GetY())); reducedPoints[newIndex] = new TwoDPoint(new_x, new_y); reference = reducedPoints[newIndex]; newIndex++; thisDistance = (coveredDistance + thisDistance) - idealInterval; coveredDistance = 0; passedIdeal = (coveredDistance + thisDistance) >= idealInterval; } coveredDistance = thisDistance; } else { coveredDistance += thisDistance; } gesture.SetPoints(reducedPoints); } }
//*************************************** // FindMatch // // use: determines template gesture with the minimum // average distance between points to the // currently recorded gesture // Called after finishing a gesture when not // recording // // param: playerGesture: current gesture to be matched // templates: object containting list of // gestures to compare against // // return: returns gesture object of the minimum // difference template private DrawnGesture FindMatch(DrawnGesture playerGesture, GestureTemplates templates) { float minAvgDifference = float.MaxValue; DrawnGesture match = new DrawnGesture("no match", pointsPerGesture); foreach (DrawnGesture template in templates.templates) { Debug.Log(template.GetName()); float d = AverageDifference(playerGesture, template); Debug.Log(d.ToString()); if (d < minAvgDifference) { minAvgDifference = d; match = template; } } return(match); }
//*************************************** // AverageDifference // // use: caluclates the average distance between // the points of two gestures // // param: playerGesture: first to be compared // template: gesture to be compared against // // return: returns float value of the average distance // between points of two parameter gestures private float AverageDifference(DrawnGesture playerGesture, DrawnGesture template) { int numPoints = playerGesture.GetNumPoints(); if (numPoints != template.GetNumPoints()) { Debug.Log("Number of points differs from templates"); return(-1f); } float totalDifference = 0; for (int i = 0; i < numPoints; i++) { totalDifference += PointDistance(playerGesture.GetPoints()[i], template.GetPoints()[i]); } return(totalDifference / numPoints); }
//*************************************** // Rescale // // use: scales recorded list of points to a square field // of a chosen size by multiplication of the factor // of the desired size it already is // Called on every gesture after recording private void Rescale(DrawnGesture gesture) { float scale = 1f; float xrange = gesture.GetMaxX() - gesture.GetMinX(); float yrange = gesture.GetMaxY() - gesture.GetMinY(); if (xrange >= yrange) { scale = standardRatio / (gesture.GetMaxX() - gesture.GetMinX()); } else { scale = standardRatio / (gesture.GetMaxY() - gesture.GetMinY()); } if (scale != 1) { foreach (TwoDPoint point in currentPointList) { point.SetX(point.GetX() * scale); point.SetY(point.GetY() * scale); } } }
//*************************************** // EndGesture // // use: Resets control bools and other variables // records gesture to the templates object // or calls recognition. // Called when max recording points reached. private void EndGesture() { if (inputReady) { inputReady = false; } gestureStarted = false; gestureComplete = true; Rescale(currentGesture); MapPoints(currentGesture); if (recording) { currentGesture.SetName(templateSaveName); templates.templates.Add(new DrawnGesture(currentGesture.GetName(), pointsPerGesture, currentGesture.GetMaxX(), currentGesture.GetMaxY(), currentGesture.GetMinX(), currentGesture.GetMinY(), currentGesture.GetPoints())); } else { DrawnGesture m = FindMatch(currentGesture, templates); Debug.Log(m.GetName()); } varReset(); }