protected virtual Frame GetNearestNeighbourAssignment(Frame lastFrame, Frame currentFrame, KdTree kdTreeCurrentTouches) { Frame trackedFrame = new Frame(currentFrame.TimeStamp); int fibHeapCount = 0; fibHeap.Initialize(MAXBLOBS); foreach (var lastTouch in lastFrame) { IVertex lastVertex = new Vertex(lastTouch.X, lastTouch.Y); int nn = kdTreeCurrentTouches.TopDownNearestNeighbour(lastVertex); Touch currentTouch = currentFrame.GetTouch(nn); IVertex currentVertex = new Vertex(currentTouch.X, currentTouch.Y); lastToCurrentAssignment[lastTouch.ID] = nn; fibHeap.InsertKey(lastTouch.ID, MetricDistances.EuclideanDistance( lastVertex, currentVertex)); fibHeapCount++; } int min; int tempCounter = 0; while ((min = fibHeap.Minimum) > -1 && (min = fibHeap.DeleteMin()) != -1) { tempCounter++; if (lastFrame.GetTouch(min) == null) { } if (!kdTreeCurrentTouches.Included(lastToCurrentAssignment[min])) { Touch lastTouch = lastFrame.GetTouch(min); IVertex lastVertex = new Vertex(lastTouch.X, lastTouch.Y); int nn = kdTreeCurrentTouches.TopDownNearestNeighbour(lastVertex); Touch currentTouch = currentFrame.GetTouch(nn); if (currentTouch == null) // trajectory ended in last frame { return(trackedFrame); // if no radii search there is no point left to connect } else { IVertex currentVertex = new Vertex(currentTouch.X, currentTouch.Y); lastToCurrentAssignment[lastTouch.ID] = currentTouch.ID; fibHeap.InsertKey(lastTouch.ID, MetricDistances.EuclideanDistance( lastVertex, currentVertex)); } continue; } Touch t = currentFrame.GetTouch(lastToCurrentAssignment[min]); kdTreeCurrentTouches.Delete(lastToCurrentAssignment[min]); Touch newTouch = new Touch(min, t.X, t.Y, t.DimX, t.DimY, t.Intense); trackedFrame.AddTouch(newTouch); } return(trackedFrame); }