public List <LookupResult> FindMatchingPairs(NeighborEdge[] probeStar, NeighborEdge[] candidateStar) { byte complementaryAngleError = Angle.Complementary(MaxAngleError); ReturnList.Clear(); Range range = new Range(); for (int candidateIndex = 0; candidateIndex < candidateStar.Length; ++candidateIndex) { NeighborEdge candidateEdge = candidateStar[candidateIndex]; while (range.Begin < probeStar.Length && probeStar[range.Begin].Edge.Length < candidateEdge.Edge.Length - MaxDistanceError) { ++range.Begin; } if (range.End < range.Begin) { range.End = range.Begin; } while (range.End < probeStar.Length && probeStar[range.End].Edge.Length <= candidateEdge.Edge.Length + MaxDistanceError) { ++range.End; } for (int probeIndex = range.Begin; probeIndex < range.End; ++probeIndex) { var probeEdge = probeStar[probeIndex]; byte referenceDiff = Angle.Difference(probeEdge.Edge.ReferenceAngle, candidateEdge.Edge.ReferenceAngle); if (referenceDiff <= MaxAngleError || referenceDiff >= complementaryAngleError) { byte neighborDiff = Angle.Difference(probeEdge.Edge.NeighborAngle, candidateEdge.Edge.NeighborAngle); if (neighborDiff <= MaxAngleError || neighborDiff >= complementaryAngleError) { ReturnList.Add(new LookupResult() { Pair = new MinutiaPair(probeEdge.Neighbor, candidateEdge.Neighbor), Distance = candidateEdge.Edge.Length }); } } } } return(ReturnList); }
void BuildTable(Template template) { Table = new NeighborEdge[template.Minutiae.Length][]; var edges = new List <NeighborEdge>(); var allSqDistances = new int[template.Minutiae.Length]; for (int reference = 0; reference < Table.Length; ++reference) { Point referencePosition = template.Minutiae[reference].Position; int sqMaxDistance = Calc.Sq(MaxDistance); if (template.Minutiae.Length - 1 > MaxNeighbors) { for (int neighbor = 0; neighbor < template.Minutiae.Length; ++neighbor) { allSqDistances[neighbor] = Calc.DistanceSq(referencePosition, template.Minutiae[neighbor].Position); } Array.Sort(allSqDistances); sqMaxDistance = allSqDistances[MaxNeighbors]; } for (int neighbor = 0; neighbor < template.Minutiae.Length; ++neighbor) { if (neighbor != reference && Calc.DistanceSq(referencePosition, template.Minutiae[neighbor].Position) <= sqMaxDistance) { NeighborEdge record = new NeighborEdge(); record.Edge = EdgeConstructor.Construct(template, reference, neighbor); record.Neighbor = neighbor; edges.Add(record); } } edges.Sort(NeighborEdgeComparer.Instance); if (edges.Count > MaxNeighbors) { edges.RemoveRange(MaxNeighbors, edges.Count - MaxNeighbors); } Table[reference] = edges.ToArray(); edges.Clear(); } }