/// <summary> /// Adds a new polygon set and looks for a possible unifications. /// Assumes both sets are distinct. /// </summary> /// <param name="pOther">The polygon set to add and possible unify.</param> public void AddAndUnify(C2DHoledPolyBaseSet pOther) { var TempSet = new C2DHoledPolyBaseSet(); while (pOther.Count > 0) { var pLast = pOther[pOther.Count - 1]; pOther.RemoveAt(pOther.Count - 1); if (!AddIfUnify(pLast)) { TempSet.Add(pLast); } } this.AddRange(TempSet); }
/// <summary> /// Unification by growing shapes of fairly equal size (fastest for large groups). /// </summary> /// <param name="grid">The CGrid with the degenerate settings.</param> public void UnifyProgressive(CGrid grid) { // Record the degenerate handling so we can reset. CGrid.eDegenerateHandling DegenerateHandling = grid.DegenerateHandling; switch (grid.DegenerateHandling) { case CGrid.eDegenerateHandling.RandomPerturbation: for (var i = 0; i < Count; i++) { this[i].RandomPerturb(); } grid.DegenerateHandling = CGrid.eDegenerateHandling.None; break; case CGrid.eDegenerateHandling.DynamicGrid: break; case CGrid.eDegenerateHandling.PreDefinedGrid: for (var i = 0; i < Count; i++) { this[i].SnapToGrid(grid); } grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGridPreSnapped; break; case CGrid.eDegenerateHandling.PreDefinedGridPreSnapped: break; } var NoUnionSet = new C2DHoledPolyBaseSet(); var PossUnionSet = new C2DHoledPolyBaseSet(); var SizeHoldSet = new C2DHoledPolyBaseSet(); var UnionSet = new C2DHoledPolyBaseSet(); var TempSet = new C2DHoledPolyBaseSet(); var nThreshold = GetMinLineCount(); if (nThreshold == 0) { nThreshold = 10; // avoid infinate loop. } // Assumed all are size held to start SizeHoldSet.AddRange(this); this.Clear(); do { // double the threshold nThreshold *= 3; // Put all the possible intersects back in this. this.AddRange(PossUnionSet); PossUnionSet.Clear(); // Put all the size held that are small enough back (or in to start with) while (SizeHoldSet.Count > 0) { var pLast = SizeHoldSet[SizeHoldSet.Count - 1]; SizeHoldSet.RemoveAt(SizeHoldSet.Count - 1); if (pLast.GetLineCount() > nThreshold) { TempSet.Add(pLast); } else { this.Add(pLast); } } SizeHoldSet.AddRange(TempSet); TempSet.Clear(); // Cycle through all popping the last and finding a union while (Count > 0) { var pLast = this[Count - 1]; this.RemoveAt(Count - 1); var bIntersect = false; var i = 0; while (i < Count && !bIntersect) { this[i].GetUnion(pLast, UnionSet, grid); if (UnionSet.Count == 1) { var pUnion = UnionSet[UnionSet.Count - 1]; UnionSet.RemoveAt(UnionSet.Count - 1); if (pUnion.GetLineCount() > nThreshold) { RemoveAt(i); SizeHoldSet.Add(pUnion); } else { this[i] = pUnion; i++; } bIntersect = true; } else { if (UnionSet.Count != 0) { grid.LogDegenerateError(); } UnionSet.Clear(); i++; } } if (!bIntersect) { var bPosInterSect = false; for (var j = 0; j < SizeHoldSet.Count; j++) { if (pLast.Rim.BoundingRect.Overlaps( SizeHoldSet[j].Rim.BoundingRect)) { bPosInterSect = true; break; } } if (bPosInterSect) { PossUnionSet.Add(pLast); } else { NoUnionSet.Add(pLast); } } } }while (SizeHoldSet.Count != 0); this.AddRange(NoUnionSet); NoUnionSet.Clear(); grid.DegenerateHandling = DegenerateHandling; }