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);
        }
示例#2
0
        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);
        }