Ejemplo n.º 1
0
        public int Compare(BasicObstacleSide first, BasicObstacleSide second)
        {
            ValidateArg.IsNotNull(first, "first");
            ValidateArg.IsNotNull(second, "second");

            // If these are two sides of the same obstacle then the ordering is obvious.
            if (first.Obstacle == second.Obstacle)
            {
                if (first == second)
                {
                    return(0);
                }

                return((first is LowObstacleSide) ? -1 : 1);
            }

            Debug_VerifySidesDoNotIntersect(first, second);

            // Other than intersecting sides at vertices of the same obstacle, there should be no interior intersections...
            Point firstIntersect  = VisibilityGraphGenerator.ScanLineIntersectSide(this.linePositionAtLastInsertOrRemove, first, scanDirection);
            Point secondIntersect = VisibilityGraphGenerator.ScanLineIntersectSide(this.linePositionAtLastInsertOrRemove, second, scanDirection);
            var   cmp             = firstIntersect.CompareTo(secondIntersect);

            // ... but we may still have rectangular sides that coincide, or angled sides that are close enough here but
            // are not detected by the convex-hull overlap calculations.  In those cases, we refine the comparison by side
            // type, with High coming before Low, and then by obstacle ordinal if needed. Because there are no interior
            // intersections, this ordering will remain valid as long as the side(s) are in the scanline.
            if (0 == cmp)
            {
                bool firstIsLow  = first is LowObstacleSide;
                bool secondIsLow = second is LowObstacleSide;
                cmp = firstIsLow.CompareTo(secondIsLow);
                if (0 == cmp)
                {
                    cmp = first.Obstacle.Ordinal.CompareTo(second.Obstacle.Ordinal);
                }
            }

            DevTraceInfo(4, "Compare {0} @ {1:F5} {2:F5} and {3:F5} {4:F5}: {5} {6}",
                         cmp, firstIntersect.X, firstIntersect.Y, secondIntersect.X, secondIntersect.Y, first, second);
            return(cmp);
        }