Esempio n. 1
0
            bool AlreadyFinished(ref Polygon polygon, OperationType ot, SweepEvent currentEvent)
            {
                if ((ot == OperationType.INTERSECTION && currentEvent.Point.x > minMaxX) ||
                    (ot == OperationType.DIFFERENCE && currentEvent.Point.x > bbSubject.max.x))
                {
                    polygon = connector.CreatePolygon();

                    return(true);
                }

                if (ot == OperationType.UNION && currentEvent.Point.x > minMaxX)
                {
                    // add all the non-processed line segments to the result
                    if (!currentEvent.Left)
                    {
                        connector.Add(currentEvent.CreateEdge());
                    }

                    while (!futureSweepLineEvents.IsEmpty())
                    {
                        currentEvent = futureSweepLineEvents.ExtractFirst();

                        if (!currentEvent.Left)
                        {
                            connector.Add(currentEvent.CreateEdge());
                        }
                    }

                    polygon = connector.CreatePolygon();

                    return(true);
                }

                return(false);
            }
Esempio n. 2
0
            void HandleRightEvent(OperationType ot, SweepEvent currentEvent)
            {
                // the left end/part of the current SweepEvent must be removed from sweepLineEvents
                left = currentEvent.Other.positionInS;
                next = left.GetSuccessor();
                prev = left.GetPredecessor();

                // Check if the line segment belongs to the Boolean operation
                switch (currentEvent.Type)
                {
                case EdgeType.NORMAL:
                    switch (ot)
                    {
                    case OperationType.INTERSECTION: if (currentEvent.Other.Inside)
                        {
                            connector.Add(currentEvent.CreateEdge());
                        }
                        break;

                    case OperationType.UNION: if (!currentEvent.Other.Inside)
                        {
                            connector.Add(currentEvent.CreateEdge());
                        }
                        break;

                    case OperationType.DIFFERENCE: if ((currentEvent.OwningPolygon == (int)Operand.SUBJECT && !currentEvent.Other.Inside) ||
                                                       (currentEvent.OwningPolygon == (int)Operand.CLIPPER && currentEvent.Other.Inside))
                        {
                            connector.Add(currentEvent.CreateEdge());
                        }
                        break;

                    case OperationType.XOR: connector.Add(currentEvent.CreateEdge());                                 break;
                    }
                    break;

                case EdgeType.SAME_TRANSITION: if (ot == OperationType.INTERSECTION || ot == OperationType.UNION)
                    {
                        connector.Add(currentEvent.CreateEdge());
                    }
                    break;

                case EdgeType.DIFFERENT_TRANSITION: if (ot == OperationType.DIFFERENCE)
                    {
                        connector.Add(currentEvent.CreateEdge());
                    }
                    break;
                }

                AddDebugEdge(currentEvent);

                sweepLineEvents.RemoveAt(left);

                if (next != null && prev != null)
                {
                    PossibleIntersection(prev.Value, next.Value);
                }
            }
Esempio n. 3
0
            /// <summary>
            /// Process a possible intersection between the segment associated to the left events e1 and e2
            /// </summary>
            void PossibleIntersection(SweepEvent e1, SweepEvent e2)
            {
                Edge edge1 = e1.CreateEdge();
                Edge edge2 = e2.CreateEdge();

                List <Vector2> intersections = edge1.GetIntersectionsWith(edge2);

                if (intersections.Count == 0)
                {
                    return;
                }
                if (intersections.Count == 1 && e1.HasEqualEndpoint(e2))
                {
                    return;
                }
                if (intersections.Count == 2 && e1.BelongsToSamePolygonAs(e2))
                {
                    return;
                }

                if (intersections.Count == 1)
                {
                    Vector2 ip = intersections[0];

                    if (!e1.IsAnEndpoint(ip))
                    {
                        DivideEdge(e1, ip);
                    }
                    if (!e2.IsAnEndpoint(ip))
                    {
                        DivideEdge(e2, ip);
                    }

                    return;
                }

                List <SweepEvent> sortedEvents = new List <SweepEvent>(); // the line segments overlap

                if (e1.Point == e2.Point)
                {
                    sortedEvents.Add(null);
                }
                else if (comparer.Compare(e1, e2) > 0)
                {
                    sortedEvents.Add(e2);
                    sortedEvents.Add(e1);
                }
                else
                {
                    sortedEvents.Add(e1);
                    sortedEvents.Add(e2);
                }

                if (e1.Other.Point == e2.Other.Point)
                {
                    sortedEvents.Add(null);
                }
                else if (comparer.Compare(e1.Other, e2.Other) > 0)
                {
                    sortedEvents.Add(e2.Other);
                    sortedEvents.Add(e1.Other);
                }
                else
                {
                    sortedEvents.Add(e1.Other);
                    sortedEvents.Add(e2.Other);
                }

                //////////////////////////////////////
                // Degeneracies : Overlapping Edges //
                //////////////////////////////////////

                // 1. Case: overlapping edges that are equal

                if (sortedEvents.Count == 2)
                {
                    e1.SetEdgeType(EdgeType.NON_CONTRIBUTING);

                    if (e1.InOut == e2.InOut)
                    {
                        e2.SetEdgeType(EdgeType.SAME_TRANSITION);
                    }
                    else
                    {
                        e2.SetEdgeType(EdgeType.DIFFERENT_TRANSITION);
                    }

                    return;
                }

                // 2. Case: overlapping edges that share an endpoint

                if (sortedEvents.Count == 3)
                {
                    sortedEvents[1].SetEdgeType(EdgeType.NON_CONTRIBUTING);

                    int sharedIndex = (sortedEvents[0] != null) ? 0 : 2; // is left endpoint or right endpoint shared

                    if (e1.InOut == e2.InOut)
                    {
                        sortedEvents[sharedIndex].Other.Type = EdgeType.SAME_TRANSITION;
                    }
                    else
                    {
                        sortedEvents[sharedIndex].Other.Type = EdgeType.DIFFERENT_TRANSITION;
                    }

                    if (sortedEvents[0] != null)
                    {
                        DivideEdge(sortedEvents[0], sortedEvents[1].Point);
                    }
                    else
                    {
                        DivideEdge(sortedEvents[2].Other, sortedEvents[1].Point);
                    }

                    return;
                }

                // 3. Case: overlapping edges where noone totally includes the other

                if (sortedEvents[0] != sortedEvents[3].Other)
                {
                    sortedEvents[1].Type = EdgeType.NON_CONTRIBUTING;
                    sortedEvents[2].Type = (e1.InOut == e2.InOut) ? EdgeType.SAME_TRANSITION : EdgeType.DIFFERENT_TRANSITION;

                    DivideEdge(sortedEvents[0], sortedEvents[1].Point);
                    DivideEdge(sortedEvents[1], sortedEvents[2].Point);

                    return;
                }

                // one line segment includes the other one
                sortedEvents[1].Type = sortedEvents[1].Other.Type = EdgeType.NON_CONTRIBUTING;
                DivideEdge(sortedEvents[0], sortedEvents[1].Point);

                sortedEvents[3].Other.Type = (e1.InOut == e2.InOut) ? EdgeType.SAME_TRANSITION : EdgeType.DIFFERENT_TRANSITION;
                DivideEdge(sortedEvents[3].Other, sortedEvents[2].Point);
            }
Esempio n. 4
0
 void AddDebugEdge(SweepEvent currentEvent)
 {
     debugEdges.Add(new DebugEdge {
         Edge = currentEvent.CreateEdge(), InOut = currentEvent.InOut, Left = currentEvent.Left, Type = currentEvent.Type
     });
 }