Пример #1
0
 internal static PolyRelInternal SwitchAAndBPolygonRelationship(this PolyRelInternal relationship)
 {
     if ((relationship & PolyRelInternal.Intersection) == PolyRelInternal.AInsideB)
     {
         relationship |= PolyRelInternal.BInsideA;
         relationship &= ~PolyRelInternal.AInsideB;
     }
     else if ((relationship & PolyRelInternal.Intersection) == PolyRelInternal.BInsideA)
     {
         relationship |= PolyRelInternal.AInsideB;
         relationship &= ~PolyRelInternal.BInsideA;
     }
     return(relationship);
 }
Пример #2
0
        internal PolygonInteractionRecord InvertPolygonInRecord(Polygon polygon, out Polygon invertedPolygon)
        {
            var  tolerance                = polygon.GetToleranceForPolygon();
            bool polygonAIsInverted       = subPolygonToInt[polygon] < numPolygonsInA;
            var  visitedIntersectionPairs = new HashSet <(PolygonEdge, PolygonEdge)>();
            var  delimiters               = PolygonBooleanBase.NumberVerticesAndGetPolygonVertexDelimiter(polygon);

            invertedPolygon = polygon.Copy(true, true);
            var allLines           = invertedPolygon.AllPolygons.SelectMany(p => p.Edges).ToList();
            var newIntersections   = new List <SegmentIntersection>();
            var possibleDuplicates = new List <(int, PolygonEdge, PolygonEdge)>();

            for (int i = 0; i < IntersectionData.Count; i++)
            {
                var oldIntersection = IntersectionData[i];
                var edgeA           = oldIntersection.EdgeA;
                var edgeB           = oldIntersection.EdgeB;
                var indexOfEdge     = polygonAIsInverted ? edgeA.IndexInList : edgeB.IndexInList;
                var k = 0;
                while (delimiters[k] <= indexOfEdge)
                {
                    k++;
                }
                indexOfEdge = delimiters[k - 1] + (delimiters[k] - indexOfEdge) - 1;
                var newFlippedEdge = allLines[indexOfEdge];
                if (oldIntersection.WhereIntersection == WhereIsIntersection.BothStarts ||
                    (polygonAIsInverted && oldIntersection.WhereIntersection == WhereIsIntersection.AtStartOfA) ||
                    (!polygonAIsInverted && oldIntersection.WhereIntersection == WhereIsIntersection.AtStartOfB))
                {
                    newFlippedEdge = newFlippedEdge.ToPoint.StartLine;
                }
                if (polygonAIsInverted)
                {
                    if (visitedIntersectionPairs.Contains((newFlippedEdge, edgeB)))
                    {
                        continue;
                    }
                    visitedIntersectionPairs.Add((newFlippedEdge, edgeB));
                    PolygonOperations.AddIntersectionBetweenLines(newFlippedEdge, edgeB, newIntersections, possibleDuplicates, tolerance);
                }
                else
                {
                    if (visitedIntersectionPairs.Contains((edgeA, newFlippedEdge)))
                    {
                        continue;
                    }
                    visitedIntersectionPairs.Add((edgeA, newFlippedEdge));
                    PolygonOperations.AddIntersectionBetweenLines(edgeA, newFlippedEdge, newIntersections, possibleDuplicates, tolerance);
                }
            }
            var newSubPolygonToInt = new Dictionary <Polygon, int>();
            var isAPositive        = invertedPolygon.IsPositive;
            var isBPositive        = invertedPolygon.IsPositive;

            if (!polygonAIsInverted)
            {
                using var newPolyEnumerator = invertedPolygon.AllPolygons.GetEnumerator();
                foreach (var keyValuePair in subPolygonToInt)
                {
                    if (keyValuePair.Value == 0)
                    {
                        isAPositive = keyValuePair.Key.IsPositive;
                    }
                    if (keyValuePair.Value < numPolygonsInA)
                    {
                        newSubPolygonToInt.Add(keyValuePair.Key, keyValuePair.Value);
                    }
                    else
                    {
                        newPolyEnumerator.MoveNext();
                        newSubPolygonToInt.Add(newPolyEnumerator.Current, keyValuePair.Value);
                    }
                }
                return(new PolygonInteractionRecord(Relationship, newIntersections, (PolyRelInternal[])polygonRelations.Clone(), newSubPolygonToInt,
                                                    numPolygonsInA, numPolygonsInB, isAPositive, isBPositive)
                {
                    CoincidentEdges = this.CoincidentEdges,
                    CoincidentVertices = this.CoincidentVertices,
                    EdgesCross = this.EdgesCross
                });
            }
            var index = 0;

            foreach (var keyValuePair in subPolygonToInt)
            {
                if (keyValuePair.Value == numPolygonsInA)
                {
                    isBPositive = keyValuePair.Key.IsPositive;
                }
                if (keyValuePair.Value >= numPolygonsInA)
                {
                    newSubPolygonToInt.Add(keyValuePair.Key, index++);
                }
            }
            foreach (var newpoly in invertedPolygon.AllPolygons)
            {
                newSubPolygonToInt.Add(newpoly, index++);
            }

            var newPolygonRelations = new PolyRelInternal[numPolygonsInA * numPolygonsInB];

            for (int i = 0; i < numPolygonsInA; i++)
            {
                for (int j = 0; j < numPolygonsInB; j++)
                {
                    newPolygonRelations[numPolygonsInB * i + j] = Constants.SwitchAAndBPolygonRelationship(polygonRelations[numPolygonsInA * j + i]);
                }
            }
            return(new PolygonInteractionRecord((PolygonRelationship)Constants.SwitchAAndBPolygonRelationship((PolyRelInternal)Relationship),
                                                newIntersections, newPolygonRelations, newSubPolygonToInt,
                                                numPolygonsInB, numPolygonsInA, isBPositive, isAPositive)
            {
                CoincidentEdges = this.CoincidentEdges,
                CoincidentVertices = this.CoincidentVertices,
                EdgesCross = this.EdgesCross
            });
        }
Пример #3
0
        internal void SetRelationshipBetween(int index, PolyRelInternal newRel)
        {
            polygonRelations[index] = newRel;
            //Separated
            //AInsideB
            //AIsInsideHoleOfB
            //BInsideA
            //BIsInsideHoleOfA
            //Intersection
            //Equal
            //EqualButOpposite
            // okay need to compare all possibilities of the PolygonRelationship enum to itself
            // there are 8 values so that 8 x 8 = 64 possibilities.
            // let's see how this breaks down
            if (this.Relationship == PolygonRelationship.Intersection)
            {
                return;
            }
            // if already Intersection, then nothing to do (that's 8)
            if (newRel == PolyRelInternal.Separated)
            {
                return;
            }
            // if the newRel is Separated then no update as well (7 more)
            var newRelationship = (PolygonRelationship)(((int)newRel) & 248);

            if (newRelationship == Relationship)
            {
                return;
            }
            // if they're the same then nothing to do (that's 6 more since previous conditions would have caught 2 of these
            // down to 43
            if (newRelationship == PolygonRelationship.Intersection ||
                ((newRelationship == PolygonRelationship.AInsideB || newRelationship == PolygonRelationship.AIsInsideHoleOfB) &&
                 (Relationship == PolygonRelationship.BInsideA || Relationship == PolygonRelationship.BIsInsideHoleOfA)) ||
                ((newRelationship == PolygonRelationship.BInsideA || newRelationship == PolygonRelationship.BIsInsideHoleOfA) &&
                 (Relationship == PolygonRelationship.AInsideB || Relationship == PolygonRelationship.AIsInsideHoleOfB)))
            {
                this.Relationship = PolygonRelationship.Intersection;
            }
            // how many more pairs are these: 7 + 8....down to 28
            else if (Relationship == PolygonRelationship.Separated)
            {
                Relationship = newRelationship; //6 more here (i think...not included newRel is Separated or Intersection
            }
            else if (newRelationship == PolygonRelationship.Equal)
            {
                return;                                                    // current Relationship would be more descriptive
            }
            // so finding out that a subpolygon in Equal doesn't change anything (that 5 more cases)
            else if (newRelationship == PolygonRelationship.EqualButOpposite)
            {
                if (Relationship == PolygonRelationship.BInsideA)
                {
                    Relationship = PolygonRelationship.BIsInsideHoleOfA;
                }
                if (Relationship == PolygonRelationship.AInsideB)
                {
                    Relationship = PolygonRelationship.AIsInsideHoleOfB;
                }
                // really need to check the new EqualButOpposite with AInsideB, AIsInsideHoleOfB, BInsideA,
                // BIsInsideHoleOfA, & Equal (so that's 5 additional cases) but the above two subcases are the
                // only ways this can ever happen, right?
            }
            // there are 12 left, all of which are either impossible or have no effect (I think). These are listed below.
            // The first 4 are possible and we need to be careful if the outer positive polygons match, then when we compare
            // the inner hole of A to the outer of B, we will get the first condition below, but we don't want to change the
            // full Relationship unless we are sure it's not identical. This requires us to have one more function at the end
            // which is DefineOverallInteractionFromFinalListOfSubInteractions
            //R = Equal , Nrel = AInsideB
            //R = Equal , Nrel = AIsInsideHoleOfB
            //R = Equal , Nrel = BInsideA
            //R = Equal , Nrel = BIsInsideHoleOfA
            //R = AIsInsideHoleOfB , Nrel = AInsideB
            //R = AInsideB , Nrel = AIsInsideHoleOfB
            //R = BIsInsideHoleOfA , Nrel = BInsideA
            //R = BInsideA , Nrel = BIsInsideHoleOfA
            //R = EqualButOpposite , Nrel = AInsideB
            //R = EqualButOpposite , Nrel = AIsInsideHoleOfB
            //R = EqualButOpposite , Nrel = BInsideA
            //R = EqualButOpposite , Nrel = BIsInsideHoleOfA
            return;
        }