示例#1
0
        public void LineSearchGridTestMethod()
        {
            LineSearchGrid<GridVector2> LineSearch = new LineSearchGrid<GridVector2>(new GridRectangle(-10, 10, -10, 10), 500);

            GridLineSegment lineA = new GridLineSegment(new GridVector2(-5, 3),
                                                        new GridVector2(5, 3));
            GridLineSegment lineB = new GridLineSegment(new GridVector2(3, -5),
                                                        new GridVector2(3, 5));
            GridLineSegment lineC = new GridLineSegment(new GridVector2(-6, -5),
                                                        new GridVector2(-6, 5));
            GridLineSegment lineD = new GridLineSegment(new GridVector2(-9, 8),
                                                        new GridVector2(1, -8));
            GridLineSegment lineE = new GridLineSegment(new GridVector2(-9, 8),
                                                        new GridVector2(1, -2));

            LineSearch.Add(lineA, lineA.A);
            LineSearch.Add(lineB, lineB.A);
            LineSearch.Add(lineC, lineC.A);
            LineSearch.Add(lineD, lineD.A);
            LineSearch.Add(lineE, lineE.B);

            GridVector2 intersection;
            double distance;
            GridVector2 value = LineSearch.GetNearest(new GridVector2(-5, 3), out intersection, out distance);
            Debug.Assert(value == lineA.A);

            value = LineSearch.GetNearest(new GridVector2(-10, -10), out intersection, out distance);
            Debug.Assert(value == lineC.A);
        }
示例#2
0
        public void LineSearchGridTestMethod()
        {
            LineSearchGrid<string> LineSearch = new LineSearchGrid<string>(new GridRectangle(-10, 10, -10, 10), 500);

            GridLineSegment lineA = new GridLineSegment(new GridVector2(-5, 3),
                                                        new GridVector2(5, 3));
            GridLineSegment lineB = new GridLineSegment(new GridVector2(3, -5),
                                                        new GridVector2(3, 5));
            GridLineSegment lineC = new GridLineSegment(new GridVector2(-6, -5),
                                                        new GridVector2(-6, 5));
            GridLineSegment lineD = new GridLineSegment(new GridVector2(-9, 8),
                                                        new GridVector2(1, -8)); //Should be in seven grid cells
            GridLineSegment lineE = new GridLineSegment(new GridVector2(-9, 8),
                                                        new GridVector2(1, -2));

            LineSearch.Add(lineA, "A");
            LineSearch.Add(lineB, "B");
            LineSearch.Add(lineC, "C");
            LineSearch.Add(lineD, "D");
            LineSearch.Add(lineE, "E");

            GridVector2 intersection;
            double distance;
            string value = LineSearch.GetNearest(new GridVector2(-5, 3), out intersection, out distance);
            Debug.Assert(value == "A");

            value = LineSearch.GetNearest(new GridVector2(-10, -10), out intersection, out distance);
            Debug.Assert(value == "C");

            value = LineSearch.GetNearest(new GridVector2(7, 4), out intersection, out distance);
            Debug.Assert(value == "A");

            value = LineSearch.GetNearest(new GridVector2(3.5, 6), out intersection, out distance);
            Debug.Assert(value == "B");
        }
示例#3
0
 internal GrdSegment(GridLineSegment segment) : base()
 {
     Ax            = segment.PointA.X;
     Ay            = segment.PointA.Y;
     Bx            = segment.PointB.X;
     By            = segment.PointB.Y;
     IsCellSegment = segment.IsCellSegment;
 }
示例#4
0
文件: LineTest.cs 项目: abordt/Viking
        public void GridLineSegmentDistanceToPoint()
        {
            //Check edge conditions for a horizontal line
            {
                GridLineSegment lineA = new GridLineSegment(new GridVector2(-5, 3),
                                                            new GridVector2(5, 3));

                //Check edge conditions for a horizontal line
                GridVector2 PointOnLine = new GridVector2(2, 3);
                double Distance;
                GridVector2 Intersection;
                Distance = lineA.DistanceToPoint(PointOnLine, out Intersection);
                Debug.Assert(Distance == 0);
                Debug.Assert(Intersection == PointOnLine);

                //Check if we go past the line in X axis
                GridVector2 PointLeftOfLine = new GridVector2(-10, 3);
                GridVector2 PointRightOfLine = new GridVector2(10, 3);
                Distance = lineA.DistanceToPoint(PointLeftOfLine, out Intersection);
                Debug.Assert(Distance == 5);
                Debug.Assert(Intersection == lineA.A);

                Distance = lineA.DistanceToPoint(PointRightOfLine, out Intersection);
                Debug.Assert(Distance == 5);
                Debug.Assert(Intersection == lineA.B);

                //Check if we go above or below line
                GridVector2 PointAboveLine = new GridVector2(3, 8);
                GridVector2 PointBelowLine = new GridVector2(3, -2);
                Distance = lineA.DistanceToPoint(PointAboveLine, out Intersection);
                Debug.Assert(Distance == 5);
                Debug.Assert(Intersection == new GridVector2(3, 3));

                Distance = lineA.DistanceToPoint(PointBelowLine, out Intersection);
                Debug.Assert(Distance == 5);
                Debug.Assert(Intersection == new GridVector2(3, 3));
            }

            //Check edge conditions for a vertical line
            {
                GridLineSegment lineB = new GridLineSegment(new GridVector2(3, -5),
                                                               new GridVector2(3, 5));

                GridVector2 PointOnLine = new GridVector2(3, 2);
                double Distance;
                GridVector2 Intersection;
                Distance = lineB.DistanceToPoint(PointOnLine, out Intersection);
                Debug.Assert(Distance == 0);
                Debug.Assert(Intersection == PointOnLine);

                //Check if we go above or below line
                GridVector2 PointAboveLine = new GridVector2(3, 10);
                GridVector2 PointBelowLine = new GridVector2(3, -10);
                Distance = lineB.DistanceToPoint(PointAboveLine, out Intersection);
                Debug.Assert(Distance == 5);
                Debug.Assert(Intersection == lineB.B);

                Distance = lineB.DistanceToPoint(PointBelowLine, out Intersection);
                Debug.Assert(Distance == 5);
                Debug.Assert(Intersection == lineB.A);

                //Check if we go left or right of line
                GridVector2 PointLeftOfLine = new GridVector2(-2, 4);
                GridVector2 PointRightOfLine = new GridVector2(8, 4);
                Distance = lineB.DistanceToPoint(PointLeftOfLine, out Intersection);
                Debug.Assert(Distance == 5);
                Debug.Assert(Intersection == new GridVector2(3, 4));

                Distance = lineB.DistanceToPoint(PointRightOfLine, out Intersection);
                Debug.Assert(Distance == 5);
                Debug.Assert(Intersection == new GridVector2(3, 4));
            }

            {   //Check the diagonal line through the axis center
                GridLineSegment lineC = new GridLineSegment(new GridVector2(-5, -5),
                                                               new GridVector2(5, 5));

                GridVector2 PointOnLine = new GridVector2(0, 0);
                double Distance;
                GridVector2 Intersection;
                Distance = lineC.DistanceToPoint(PointOnLine, out Intersection);
                Debug.Assert(Distance == 0);
                Debug.Assert(Intersection == PointOnLine);

                GridVector2 PointOffLine = new GridVector2(-5, 5);
                Distance = lineC.DistanceToPoint(PointOffLine, out Intersection);
                Debug.Assert(Distance == Math.Sqrt(Math.Pow(5, 2) + Math.Pow(5,2)));
                Debug.Assert(Intersection == new GridVector2(0,0));

                GridVector2 PointPastEdge = new GridVector2(-10, 0);
                Distance = lineC.DistanceToPoint(PointPastEdge, out Intersection);
                Debug.Assert(Distance == Math.Sqrt(Math.Pow(5, 2) + Math.Pow(5,2)));
                Debug.Assert(Intersection == new GridVector2(-5,-5));
            }

            {   //Check the diagonal line through the axis center
                GridLineSegment lineD = new GridLineSegment(new GridVector2(-6, -4),
                                                               new GridVector2(4, 6));

                GridVector2 PointOnLine = new GridVector2(-1, 1);
                double Distance;
                GridVector2 Intersection;
                Distance = lineD.DistanceToPoint(PointOnLine, out Intersection);
                Debug.Assert(Distance == 0);
                Debug.Assert(Intersection == PointOnLine);

                GridVector2 PointOffLine = new GridVector2(-6, 6);
                Distance = lineD.DistanceToPoint(PointOffLine, out Intersection);
                Debug.Assert(Distance == Math.Sqrt(Math.Pow(5, 2) + Math.Pow(5, 2)));
                Debug.Assert(Intersection == new GridVector2(-1, 1));

                GridVector2 PointPastEdge = new GridVector2(9, 1);
                Distance = lineD.DistanceToPoint(PointPastEdge, out Intersection);
                Debug.Assert(Distance == Math.Sqrt(Math.Pow(5, 2) + Math.Pow(5, 2)));
                Debug.Assert(Intersection == new GridVector2(4, 6));
            }
        }
示例#5
0
文件: LineTest.cs 项目: abordt/Viking
        public void GridLineSegmentIntersects()
        {
            //
            // TODO: Add test logic	here
            //

            GridLineSegment lineA = new GridLineSegment(new GridVector2(-5,3),
                                                        new GridVector2(5,3));
            GridLineSegment lineB = new GridLineSegment(new GridVector2(3,-5),
                                                        new GridVector2(3,5));
            GridLineSegment lineC = new GridLineSegment(new GridVector2(-6, -5),
                                                        new GridVector2(-6, 5));
            GridLineSegment lineD = new GridLineSegment(new GridVector2(-9, 8),
                                                        new GridVector2(1, -8));
            GridLineSegment lineE = new GridLineSegment(new GridVector2(-9, 8),
                                                        new GridVector2(1, -2));

            GridVector2 intersect = new GridVector2();
            bool result = lineA.Intersects(lineB, out intersect);
            Debug.Assert(result == true);
            Debug.Assert(intersect.X == 3 && intersect.Y == 3);

            result = lineA.Intersects(lineC, out intersect);
            Debug.Assert(result == false);

            result = lineA.Intersects(lineD, out intersect);
            Debug.Assert(result == false);
              //      Debug.Assert(intersect.X == -4 && intersect.Y == 3);

            result = lineA.Intersects(lineE, out intersect);
            Debug.Assert(result == true);
            Debug.Assert(intersect.X == -4 && intersect.Y == 3);
        }
示例#6
0
        public double NearestLine(GridLineSegment L, out GridLineSegment foundCtrlLine, out GridLineSegment foundMapLine, out GridVector2 intersection)
        {
            double nearestIntersect = double.MaxValue;

            //For debugging only
            double nearestFailedIntersect = double.MaxValue;
            GridVector2 nearestFailedPoint = new GridVector2();
            GridLineSegment nearestFailedSegment;

            foundCtrlLine = new GridLineSegment();
            foundMapLine = new GridLineSegment();
            intersection = new GridVector2();

            IEnumerable<GridLineSegmentPair> _linePairs = _LineSegmentGrid.GetPotentialIntersections(L);

            foreach (GridLineSegmentPair pair in _linePairs)
            {
                //Build the edge and find out if it intersects
                GridLineSegment mapLine = pair.mapLine;

                if (mapLine.MinX > L.MaxX)
                    continue;
                if (mapLine.MaxX < L.MinX)
                    continue;
                if (mapLine.MinY > L.MaxY)
                    continue;
                if (mapLine.MaxY < L.MinY)
                    continue;

                GridVector2 result;
                bool bIntersected = mapLine.Intersects(L, out result);
                double distance = GridVector2.Distance(L.A, result);
                if (distance < nearestIntersect && bIntersected)
                {
                    nearestIntersect = distance;
                    intersection = result;
                    foundMapLine = mapLine;
                    foundCtrlLine = pair.ctrlLine;
                }
                if (distance < nearestFailedIntersect && !bIntersected)
                {
                    nearestFailedPoint = result;
                    nearestFailedSegment = mapLine;
                    nearestFailedIntersect = distance;
                }
            }

            return nearestIntersect;
        }
示例#7
0
        public override double ConvexHullIntersection(GridLineSegment L, GridVector2 OutsidePoint, out GridLineSegment foundCtrlLine, out GridLineSegment foundMapLine, out GridVector2 intersection)
        {
            double distance = double.MaxValue;
            foundCtrlLine = new GridLineSegment();
            foundMapLine = new GridLineSegment();
            intersection = new GridVector2();
            //In the grid transform we can simply calculate where the edge intersects if needed
            //The only place we expect this to be called is for intersections with the outside border, but we should implement it completely to be safe

            //Check the edges first
            if (MappedBounds.Intersects(L.BoundingBox) == false)
                return distance;

            GridLineSegment[] Borders = new GridLineSegment[] { MappedBounds.LeftEdge,
                                                                MappedBounds.RightEdge,
                                                                MappedBounds.TopEdge,
                                                                MappedBounds.BottomEdge};

            Direction[] BorderDir = new Direction[] { Direction.LEFT,
                                                      Direction.RIGHT,
                                                      Direction.TOP,
                                                      Direction.BOTTOM};

            GridVector2 BestIntersection = new GridVector2();
            Direction IntersectDir = Direction.NONE;
            for(int iBorder = 0; iBorder < Borders.Length; iBorder++)
            {
                GridVector2 BorderIntersect;
                bool success = L.Intersects(Borders[iBorder], out BorderIntersect);
                if(success)
                {
                    double IntersectDistance = GridVector2.Distance(OutsidePoint, BorderIntersect);
                    if(IntersectDistance < distance)
                    {
                        distance = IntersectDistance;
                        BestIntersection = BorderIntersect;
                        IntersectDir = BorderDir[iBorder];
                        intersection = BestIntersection;
                    }
                }
            }

            if(IntersectDir == Direction.NONE)
            {
                //Nothing found, stop
                return distance;
            }

            //Figure out the coordinates for L.A
            double X = ((BestIntersection.X - MappedBounds.Left) / MappedBounds.Width) * (GridSizeX - 1);
            double Y = ((BestIntersection.Y - MappedBounds.Bottom) / MappedBounds.Height) * (GridSizeY - 1);

            int iX = (int)X;
            int iY = (int)Y;

            GridLineSegmentPair pair = LinesForCoord(iX, iY, IntersectDir);

            GridVector2 testIntersection;

            double RoundErrorTestValue = 0;

            if (IntersectDir == Direction.RIGHT || IntersectDir == Direction.LEFT)
            {
                RoundErrorTestValue = X - Math.Floor(X);
            }
            else
            {
               RoundErrorTestValue = Y - Math.Floor(Y);
            }

            if (RoundErrorTestValue > 0.99)
            {
                //OK, better check if there is a rounding error we need to correct.
                if (!L.Intersects(foundMapLine, out testIntersection))
                {
                    //OK, probably a rounding error for a point very close to the end of the line
                    if (IntersectDir == Direction.RIGHT || IntersectDir == Direction.LEFT)
                    {
                        iX = (int)Math.Round(X);
                    }
                    else
                    {
                        iY = (int)Math.Round(Y);
                    }

                    pair = LinesForCoord(iX, iY, IntersectDir);
                    Debug.Assert(L.Intersects(pair.mapLine, out testIntersection));
                }

            }

            Debug.Assert(L.Intersects(pair.mapLine, out testIntersection));

            foundCtrlLine = pair.ctrlLine;
            foundMapLine = pair.mapLine;

            return distance;
        }
示例#8
0
        public void ThreadPoolCallback(Object threadContext)
        {
            List<MappingGridVector2> newPointsList = new List<MappingGridVector2>(iPoints.Length);

            foreach(int iPoint in iPoints)
            {
                MappingGridVector2 UnmappedPoint = warpingTransform.MapPoints[iPoint];
                GridVector2 newControl;
                bool TransformSuccess = fixedTransform.TryTransform(UnmappedPoint.ControlPoint, out newControl);
                if (TransformSuccess)
                {
                    newPointsList.Add( new MappingGridVector2(newControl, UnmappedPoint.MappedPoint) );
                }
                else
                {
                    this.AllPointsTransformed = false;
                    //In this case we need to test each edge connecting this point to other points.
                    List<int> MovingEdgeIndicies = warpingTransform.Edges[iPoint];

                    //Find out which of these edge points intersect triangles in the fixed warp.  If they are inside the control warp
                    //triangle mesh we find the point where the edge intersects the fixed warp mesh.
                    for (int iEdge = 0; iEdge < MovingEdgeIndicies.Count; iEdge++)
                    {
                        int iEdgePoint = MovingEdgeIndicies[iEdge];

                        GridLineSegment ctrlLine = new GridLineSegment(UnmappedPoint.ControlPoint, this.warpingTransform.MapPoints[iEdgePoint].ControlPoint);
                        GridLineSegment mapLine = new GridLineSegment(UnmappedPoint.MappedPoint, this.warpingTransform.MapPoints[iEdgePoint].MappedPoint);

                        GridLineSegment foundCtrlLine; //Control line found in nearest line call
                        GridLineSegment foundMapLine; //Corresponding map line found in nearest line call
                        GridVector2 intersect;

                        //Find out if there is a line in the fixed transform we intersect with.
                        double distance = fixedTransform.ConvexHullIntersection(ctrlLine, UnmappedPoint.ControlPoint, out foundCtrlLine, out foundMapLine, out intersect);
                        if (distance == double.MaxValue)
                            continue;

                        if (fixedTransform.GetTransform(this.warpingTransform.MapPoints[iEdgePoint].ControlPoint) == null)
                            continue;

                        //Translate from the fixed transform map space into control space.
                        GridVector2 newCtrlPoint;
                        {

                            //Determine how far along the mapping line on the fixed transfrom is the intersect point.
                            double mapLineDistance = GridVector2.Distance(foundMapLine.A, intersect);
                            double mapLineFraction = mapLineDistance / foundMapLine.Length;

                            //How far along the corresponding control line are we?
                            double ctrlLineDistance = foundCtrlLine.Length * mapLineFraction;

                            newCtrlPoint = foundCtrlLine.Direction; //Get unit vector describing direction and scale it
                            newCtrlPoint.Scale(ctrlLineDistance);
                            newCtrlPoint = newCtrlPoint + foundCtrlLine.A;
                        }

                        //Now we must find out where the point on the warping transform is by checking how far along the mapping line on the warping transform we were.
                        GridVector2 newMapPoint;
                        {
                            //Figure out where the transformed point lies in the moving transform mapped space.
                            //Make sure we measure from the same origin on both mapped and control lines
                            double CtrlLineDistance = GridVector2.Distance(ctrlLine.A, intersect);
                            double fraction = CtrlLineDistance / ctrlLine.Length;

                            Debug.Assert(fraction <= 1.0 && fraction >= 0.0);
                            if (fraction > 1f)
                                fraction = 1f;
                            else if (fraction < 0f)
                                fraction = 0f;

                            double mappedDistance = mapLine.Length * fraction;

                            newMapPoint = mapLine.Direction;
                            newMapPoint.Scale(mappedDistance);
                            newMapPoint = newMapPoint + mapLine.A;
                        }

                        newPointsList.Add(new MappingGridVector2(newCtrlPoint, newMapPoint));
                    }

                }
            }

            MappingGridVector2.RemoveDuplicates(newPointsList);
            newPoints = newPointsList.ToArray();
            DoneEvent.Set();
        }
        private void AddStructureLink(StructureObj SourceObj, SortedList<long, GridVector2> SourcePositions, long TargetStructID)
        {
            ConcurrentDictionary<long, LocationObj> LinkedLocationsOnSection;
            bool success = LocationsForStructure.TryGetValue(TargetStructID, out LinkedLocationsOnSection);
            if (success == false)
                return;

            SortedList<long, GridVector2> TargetPositions = new SortedList<long, GridVector2>(LinkedLocationsOnSection.Count);

            foreach (long locID in LinkedLocationsOnSection.Keys)
            {
                GridVector2 position;
                bool Success = TransformedLocationPositionDict.TryGetValue(locID, out position);

                if (Success)
                    TargetPositions.Add(locID, position);
            }

            long BestSourceLocID = -1;
            long BestTargetLocID = -1;
            GridVector2 Origin = new GridVector2();
            GridVector2 Destination = new GridVector2();
            double MinDistance = double.MaxValue;

            //Brute force a search for the shortest distance between the two structures.
            foreach (long SourceID in SourcePositions.Keys)
            {
                GridVector2 SourcePos = SourcePositions[SourceID];

                foreach (long TargetID in TargetPositions.Keys)
                {
                    GridVector2 TargetPos = TargetPositions[TargetID];

                    double dist = GridVector2.Distance(SourcePos, TargetPos);
                    if (dist < MinDistance)
                    {
                        BestSourceLocID = SourceID;
                        BestTargetLocID = TargetID;
                        Origin = SourcePos;
                        Destination = TargetPos;
                        MinDistance = dist;
                    }
                }
            }

            //Could not find a pair
            if (MinDistance == double.MaxValue)
                return;

            StructureObj TargetStruct = Store.Structures.GetObjectByID(TargetStructID);
            GridLineSegment lineSegment = new GridLineSegment(Origin, Destination);
            StructureLinkObj StructLink = new StructureLinkObj(SourceObj.ID, TargetStructID,
                                                               Locations[BestSourceLocID],
                                                               Locations[BestTargetLocID],
                                                               lineSegment);

            StructLink.AfterDelete += StructureLinkDeletedEventHandler;

            if (StructureLinksSearch.Contains(lineSegment))
            {
                StructureLinkObj oldLink = StructureLinksSearch[lineSegment];
                oldLink.AfterDelete -= StructureLinkDeletedEventHandler;
                StructureLinksSearch.Remove(lineSegment);
            }

            StructureLinksSearch.Add(lineSegment, StructLink);
        }
示例#10
0
        /// <summary>
        /// All locations which are linked get a line between them
        /// </summary>
        internal void RemoveLocationLinks(LocationObj obj)
        {
            foreach (long linkedID in obj.Links)
            {
                GridVector2 position;
                GridVector2 linkedPosition;

                bool success = TransformedLocationPositionDict.TryGetValue(obj.ID, out position);
                if (!success)
                    continue;

                success = TransformedLocationPositionDict.TryGetValue(linkedID, out linkedPosition);
                if (!success)
                    continue;

                GridLineSegment lineSegment = new GridLineSegment(position, linkedPosition);
                LocationLinkObj oldLink = null;
                success = LocationLinksSearch.TryRemove(lineSegment, out oldLink);
                if(success)
                {
                    oldLink.OnAfterDelete -= LocationLinkDeletedEventHandler;
                }
            }
        }
示例#11
0
        /// <summary>
        /// All locations which are linked get a line between them
        /// </summary>
        internal void AddLocationLinks(LocationObj obj)
        {
            //Only add objects in the same section
            if (obj.Z != Section.Number)
            {
                return;
            }

            foreach (long linkedID in obj.Links)
            {
                GridVector2 position;
                GridVector2 linkedPosition;

                bool success = TransformedLocationPositionDict.TryGetValue(obj.ID, out position);
                if (!success)
                    continue;

                success = TransformedLocationPositionDict.TryGetValue(linkedID, out linkedPosition);
                if (!success)
                    continue;

                GridLineSegment lineSegment = new GridLineSegment(position, linkedPosition);
                LocationLinkObj locLink = new LocationLinkObj(obj, linkedID, lineSegment);

                locLink.OnAfterDelete += LocationLinkDeletedEventHandler;

                LocationLinkObj oldLink = null;
                success = LocationLinksSearch.TryRemove(lineSegment, out oldLink);
                if (oldLink != null)
                {
                    oldLink.OnAfterDelete -= LocationLinkDeletedEventHandler;
                }

                success = LocationLinksSearch.TryAdd(lineSegment, locLink);
            }
        }
示例#12
0
        private bool AddLocationLinkToSectionSearchGrids(LocationObj AObj, LocationObj BObj, LocationLink linkView)
        {
            int minSection = AObj.Section < BObj.Section ? AObj.Section : BObj.Section;
            int maxSection = AObj.Section < BObj.Section ? BObj.Section : AObj.Section;

            GridLineSegment lineSegment = new GridLineSegment(AObj.VolumePosition, BObj.VolumePosition);

            bool success = false;
            //Add a grid line segment to each section the link intersects
            for (int iSection = minSection; iSection <= maxSection; iSection++)
            {
                //TODO: Check for missing sections!
                if (parent.Section.VolumeViewModel.SectionViewModels.ContainsKey(iSection) == false)
                    continue;

                //int EstimatedLinks = Store.Locations.GetObjectsForSection(iSection).Count;
                //if (EstimatedLinks < 2000)
                int EstimatedLinks = 2500;

                LineSearchGrid<LocationLink> searchGrid = GetOrAddSearchGrid(iSection, EstimatedLinks);
                //           Debug.WriteLine(iSection.ToString() + " add    : " + linkView.ToString() + " " + searchGrid.Count.ToString());

                //Debug.Assert(false == searchGrid.Contains(linkView));
                bool sectionSuccess = searchGrid.TryAdd(lineSegment, linkView);
                success = success || sectionSuccess;  //I had this on one line, but short-circuit logic had me beating my head against the wall for too long
                //Debug.Assert(success);
            }

            return success;
        }