public IndexedEdge Select(EdgeShape candidate) { object value; if (Hash.TryGetValue(EdgeLookup.ComputeHash(candidate), out value)) { CurrentList = value as List<IndexedEdge>; if (CurrentList == null) { var entry = value as IndexedEdge; if (EdgeLookup.MatchingEdges(entry.Shape, candidate)) return entry; else return null; } else { for (CurrentOffset = 0; CurrentOffset < CurrentList.Count; ++CurrentOffset) if (EdgeLookup.MatchingEdges(CurrentList[CurrentOffset].Shape, candidate)) { CurrentCandidate = candidate; return CurrentList[CurrentOffset++]; } return null; } } else return null; }
public bool MatchingEdges(EdgeShape probe, EdgeShape candidate) { int lengthDelta = probe.Length - candidate.Length; if (lengthDelta >= -MaxDistanceError && lengthDelta <= MaxDistanceError) { byte complementaryAngleError = Angle.Complementary(MaxAngleError); byte referenceDelta = Angle.Difference(probe.ReferenceAngle, candidate.ReferenceAngle); if (referenceDelta <= MaxAngleError || referenceDelta >= complementaryAngleError) { byte neighborDelta = Angle.Difference(probe.NeighborAngle, candidate.NeighborAngle); if (neighborDelta <= MaxAngleError || neighborDelta >= complementaryAngleError) return true; } } return false; }
public IEnumerable<int> HashCoverage(EdgeShape edge) { int minLengthBin = (edge.Length - MaxDistanceError) / MaxDistanceError; int maxLengthBin = (edge.Length + MaxDistanceError) / MaxDistanceError; int angleBins = Calc.DivRoundUp(256, MaxAngleError); int minReferenceBin = Angle.Difference(edge.ReferenceAngle, MaxAngleError) / MaxAngleError; int maxReferenceBin = Angle.Add(edge.ReferenceAngle, MaxAngleError) / MaxAngleError; int endReferenceBin = (maxReferenceBin + 1) % angleBins; int minNeighborBin = Angle.Difference(edge.NeighborAngle, MaxAngleError) / MaxAngleError; int maxNeighborBin = Angle.Add(edge.NeighborAngle, MaxAngleError) / MaxAngleError; int endNeighborBin = (maxNeighborBin + 1) % angleBins; 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) yield return (referenceBin << 24) + (neighborBin << 16) + lengthBin; }
public int ComputeHash(EdgeShape edge) { return (edge.ReferenceAngle / MaxAngleError << 24) + (edge.NeighborAngle / MaxAngleError << 16) + edge.Length / MaxDistanceError; }
public int ComputeHash(EdgeShape edge) { return((edge.ReferenceAngle / MaxAngleError << 24) + (edge.NeighborAngle / MaxAngleError << 16) + edge.Length / MaxDistanceError); }