static List <int> ShapeCoverage(EdgeShape edge) { int minLengthBin = (edge.Length - Parameters.MaxDistanceError) / Parameters.MaxDistanceError; int maxLengthBin = (edge.Length + Parameters.MaxDistanceError) / Parameters.MaxDistanceError; int angleBins = (int)Math.Ceiling(2 * Math.PI / Parameters.MaxAngleError); int minReferenceBin = (int)(DoubleAngle.Difference(edge.ReferenceAngle, Parameters.MaxAngleError) / Parameters.MaxAngleError); int maxReferenceBin = (int)(DoubleAngle.Add(edge.ReferenceAngle, Parameters.MaxAngleError) / Parameters.MaxAngleError); int endReferenceBin = (maxReferenceBin + 1) % angleBins; int minNeighborBin = (int)(DoubleAngle.Difference(edge.NeighborAngle, Parameters.MaxAngleError) / Parameters.MaxAngleError); int maxNeighborBin = (int)(DoubleAngle.Add(edge.NeighborAngle, Parameters.MaxAngleError) / Parameters.MaxAngleError); int endNeighborBin = (maxNeighborBin + 1) % angleBins; var coverage = new List <int>(); for (int lengthBin = minLengthBin; lengthBin <= maxLengthBin; ++lengthBin) { for (int referenceBin = minReferenceBin; referenceBin != endReferenceBin; referenceBin = (referenceBin + 1) % angleBins) { for (int neighborBin = minNeighborBin; neighborBin != endNeighborBin; neighborBin = (neighborBin + 1) % angleBins) { coverage.Add((referenceBin << 24) + (neighborBin << 16) + lengthBin); } } } return(coverage); }
public EdgeShape(ImmutableMinutia reference, ImmutableMinutia neighbor) { IntPoint vector = neighbor.Position - reference.Position; double quadrant = 0; int x = vector.X; int y = vector.Y; if (y < 0) { x = -x; y = -y; quadrant = Math.PI; } if (x < 0) { int tmp = -x; x = y; y = tmp; quadrant += DoubleAngle.HalfPi; } int shift = 32 - (int)Integers.LeadingZeros(((uint)x | (uint)y) >> PolarCacheBits); int offset = (y >> shift) * PolarCacheRadius + (x >> shift); Length = PolarDistanceCache[offset] << shift; double angle = PolarAngleCache[offset] + quadrant; ReferenceAngle = DoubleAngle.Difference(reference.Direction, angle); NeighborAngle = DoubleAngle.Difference(neighbor.Direction, DoubleAngle.Opposite(angle)); }
static bool MatchingShapes(EdgeShape probe, EdgeShape candidate) { int lengthDelta = probe.Length - candidate.Length; if (lengthDelta >= -Parameters.MaxDistanceError && lengthDelta <= Parameters.MaxDistanceError) { double complementaryAngleError = DoubleAngle.Complementary(Parameters.MaxAngleError); double referenceDelta = DoubleAngle.Difference(probe.ReferenceAngle, candidate.ReferenceAngle); if (referenceDelta <= Parameters.MaxAngleError || referenceDelta >= complementaryAngleError) { double neighborDelta = DoubleAngle.Difference(probe.NeighborAngle, candidate.NeighborAngle); if (neighborDelta <= Parameters.MaxAngleError || neighborDelta >= complementaryAngleError) { return(true); } } } return(false); }
List <MinutiaPair> MatchPairs(NeighborEdge[] probeStar, NeighborEdge[] candidateStar) { double complementaryAngleError = DoubleAngle.Complementary(Parameters.MaxAngleError); var results = new List <MinutiaPair>(); int start = 0; int end = 0; for (int candidateIndex = 0; candidateIndex < candidateStar.Length; ++candidateIndex) { var candidateEdge = candidateStar[candidateIndex]; while (start < probeStar.Length && probeStar[start].Length < candidateEdge.Length - Parameters.MaxDistanceError) { ++start; } if (end < start) { end = start; } while (end < probeStar.Length && probeStar[end].Length <= candidateEdge.Length + Parameters.MaxDistanceError) { ++end; } for (int probeIndex = start; probeIndex < end; ++probeIndex) { var probeEdge = probeStar[probeIndex]; double referenceDiff = DoubleAngle.Difference(probeEdge.ReferenceAngle, candidateEdge.ReferenceAngle); if (referenceDiff <= Parameters.MaxAngleError || referenceDiff >= complementaryAngleError) { double neighborDiff = DoubleAngle.Difference(probeEdge.NeighborAngle, candidateEdge.NeighborAngle); if (neighborDiff <= Parameters.MaxAngleError || neighborDiff >= complementaryAngleError) { var pair = Allocate(); pair.Probe = probeEdge.Neighbor; pair.Candidate = candidateEdge.Neighbor; pair.Distance = candidateEdge.Length; results.Add(pair); } } } } return(results); }