private CupWrapper?SubtractCurrentFrom(CupWrapper subtractFromW, AngleFunc angleFunc, System.Action <CupWrapper> OnTrimmingCreated)
        {
            Profiler.BeginSample("SubtractCurrentFrom");
            Cup?subtractFrom = subtractFromW;


            //foreach (var current in currentCups) {
            //    Debug.Assert(current.AngleOverlaps(subtractFromW));
            //}

            foreach (CupWrapper dataCup in currentCups)
            {
                if (dataCup.AngleOverlaps(subtractFromW) && ((Cup)subtractFrom).Subtract(dataCup, out Cup? before, out Cup? after, epsilon))
                {
                    subtractFrom = null;

                    void HandleSubtractResult(Cup?subtractionResult)
                    {
                        if (subtractionResult is Cup c)
                        {
                            var resultW = new CupWrapper(c, subtractFromW.obj, angleFunc);
                            // Only keep subtracting from subtractFrom if its
                            // p1 angle remains unchanged. If its p1 angle changes, this class can't handle it any more, and it goes into the trimmings.
                            if (resultW.p1Angle <= subtractFromW.p1Angle)
                            {
                                Debug.Assert(subtractFrom == null);
                                subtractFrom = c;
                            }
                            else
                            {
                                OnTrimmingCreated(resultW);
                            }
                        }
                    }

                    HandleSubtractResult(before);
                    HandleSubtractResult(after);
                }

                if (subtractFrom == null)
                {
                    Profiler.EndSample();
                    return(null);
                }
            }
            Profiler.EndSample();
            return(new CupWrapper((Cup)subtractFrom, subtractFromW.obj, angleFunc));
        }
 private bool CupComesAfterExistingCups(CupWrapper cupW)
 {
     foreach (var other in currentCups)
     {
         if (cupW.p1Angle < other.p1Angle)
         {
             return(false);
         }
     }
     foreach (var other in resultCups)
     {
         if (cupW.p1Angle < other.p1Angle)
         {
             return(false);
         }
     }
     return(true);
 }
        private void SubtractFromCurrent(CupWrapper toSubtract, AngleFunc angleFunc, System.Action <CupWrapper> OnTrimmingCreated)
        {
            Profiler.BeginSample("SubtractFromCurrent");
            Swap(ref dataTmp, ref currentCups);
            currentCups.Clear();

            //foreach (var current in dataTmp) {
            //    Debug.Assert(current.AngleOverlaps(toSubtract));
            //}

            foreach (var current in dataTmp)
            {
                if (current.AngleOverlaps(toSubtract) && current.v.Subtract(toSubtract, out Cup? beforeNullable, out Cup? afterNullable, epsilon))
                {
                    void Do(Cup?subtractionResult)
                    {
                        if (subtractionResult is Cup c)
                        {
                            var result = new CupWrapper(c, current.obj, angleFunc);
                            if (result.MidpointAngle() <= toSubtract.MidpointAngle())
                            {
                                resultCups.InsertSorted(result);
                            }
                            else
                            {
                                OnTrimmingCreated(result);
                            }
                        }
                    }

                    Do(beforeNullable);
                    Do(afterNullable);
                }
                else
                {
                    currentCups.InsertSorted(current);
                }
            }

            dataTmp.Clear();
            Profiler.EndSample();
        }
Ejemplo n.º 4
0
        private void SubtractFromCurrent(CupWrapper toSubtract, System.Action <CupWrapper> OnTrimmingCreated)
        {
            Profiler.BeginSample("SubtractFromCurrent");
            Swap(ref dataTmp, ref currentCups);
            currentCups.Clear();

            foreach (var current in dataTmp)
            {
                if (current.Subtract(toSubtract, out CupWrapper? before, out CupWrapper? after, epsilon))
                {
                    void HandleSubtractResult(CupWrapper result)
                    {
                        if (result.MidpointAngle() <= toSubtract.MidpointAngle())
                        {
                            resultCups.InsertSorted(result);
                        }
                        else
                        {
                            OnTrimmingCreated(result);
                        }
                    }

                    if (before is CupWrapper bef)
                    {
                        HandleSubtractResult(bef);
                    }
                    if (after is CupWrapper aft)
                    {
                        HandleSubtractResult(aft);
                    }
                }
                else
                {
                    currentCups.InsertSorted(current);
                }
            }

            dataTmp.Clear();
            Profiler.EndSample();
        }
Ejemplo n.º 5
0
        // PRECONDITION: Every cup passed into this function must have a larger
        // p1Angle than the previous cup passed in.
        public void Add(CupWrapper cupW, System.Action <CupWrapper> OnTrimmingCreated)
        {
            Profiler.BeginSample("SimplifiedMinimalUnion.Add");
            if (!CupComesAfterExistingCups(cupW))
            {
                Debug.Assert(false, "Cup comes before existing cup");
                Profiler.EndSample();
                return;
            }

            MoveCurrentNonOverlappingToResults(cupW);

            if (SubtractCurrentFrom(cupW, OnTrimmingCreated) is CupWrapper trimmed)
            {
                Debug.Assert(trimmed.p1Angle <= cupW.p1Angle);

                // TODO: I don't think this is necessary
                MoveCurrentNonOverlappingToResults(trimmed);
                SubtractFromCurrent(trimmed, OnTrimmingCreated);
                currentCups.InsertSorted(trimmed);
            }
            Profiler.EndSample();
        }
        // PRECONDITION: Every cup passed into this function must have a larger
        // p1Angle than the previous cup passed in.
        public void Add(CupWrapper cupW, AngleFunc angleFunc, System.Action <CupWrapper> OnTrimmingCreated)
        {
            if (!CupComesAfterExistingCups(cupW))
            {
                Debug.Assert(false, "Cup comes before existing cup");
            }

            MoveCurrentNonOverlappingToResults(cupW, angleFunc);

            if (SubtractCurrentFrom(cupW, angleFunc, OnTrimmingCreated) is CupWrapper cup)
            {
                CupWrapper trimmed = new CupWrapper(cup, cupW.obj, angleFunc);
                if (trimmed.p1Angle > cupW.p1Angle)
                {
                    OnTrimmingCreated(trimmed);
                }
                else
                {
                    MoveCurrentNonOverlappingToResults(trimmed, angleFunc);
                    SubtractFromCurrent(trimmed, angleFunc, OnTrimmingCreated);
                    currentCups.InsertSorted(trimmed);
                }
            }
        }
 private void AddTrimmingFunc(CupWrapper cupW)
 {
     futureCups.InsertSorted(cupW);
 }
 public void Add(CupWrapper cupW, AngleFunc angleFunc)
 {
     AddFutureCupsComingBefore(cupW, angleFunc);
     simpleMinUnion.Add(cupW, angleFunc, AddTrimming);
 }
Ejemplo n.º 9
0
 public void Add(CupWrapper cupW)
 {
     AddFutureCupsComingBefore(cupW);
     simpleMinUnion.Add(cupW, AddTrimming);
 }