//public void DebugOut() //{ // // String strOut = new string("r"); // String strOut = String.Format("Count {0} \n", Count); // System.Diagnostics.Trace.TraceInformation(strOut); // for (int i = 0; i < Count; i++) // { // String strOut0 = String.Format("{0}: Count {1} ", i, this[i].Count); // // System.Diagnostics.Trace.TraceInformation(strOut); // //for (int j = 0 ; j < this->GetAt(i)->size(); j++) // //{ // // C2DPoint p1 = this->GetAt(i)->GetAt(j)->GetPointFrom(); // // sprintf(buff, "x:%f y:%f", p1.x, p1.y); // //} // C2DPoint p1 = this[i][0].GetPointFrom(); // String strOut1 = String.Format("From x:{0} y:{1}", p1.x, p1.y); // // System.Diagnostics.Trace.TraceInformation(strOut); // C2DPoint p2 = this[i][this[i].Count - 1].GetPointTo(); // String strOut2 = String.Format("To x:{0} y:{1} \n", p2.x, p2.y); // System.Diagnostics.Trace.TraceInformation(strOut0 + strOut1 + strOut2); // } //} /// <summary> /// Adds all the routes from the other to this if the join a routes in this. /// </summary> /// <param name="Other">The other set.</param> public void AddJoining(C2DLineBaseSetSet Other) { C2DLineBaseSetSet Temp = new C2DLineBaseSetSet(); while (Other.Count > 0) { C2DLineBaseSet pLast = Other.ExtractAt(Other.Count - 1); int i = 0; while (i < Count) { if (!this[i].IsClosed(true) && this[i].AddIfCommonEnd(pLast)) { pLast = null; i += Count; // escape } i++; } if (pLast != null) { Temp.Add(pLast); } } while (Temp.Count > 0) { Other.Add(Temp.ExtractAt(Temp.Count - 1)); } }
/// <summary> /// Adds the routes in the other set that are closed. /// </summary> /// <param name="Other">The other set.</param> /// <param name="bEndsOnly">True if only the ends require checking.</param> public void AddClosed(C2DLineBaseSetSet Other, bool bEndsOnly) { C2DLineBaseSetSet Temp = new C2DLineBaseSetSet(); while (Other.Count > 0) { C2DLineBaseSet pLast = Other.ExtractAt(Other.Count - 1); if (pLast.IsClosed(bEndsOnly)) { this.Add(pLast); } else { Temp.Add(pLast); } } while (Temp.Count > 0) { Other.Add(Temp.ExtractAt(Temp.Count - 1)); } }
/// <summary> /// Merges the joining routes together if there are any. /// </summary> public void MergeJoining() { C2DLineBaseSetSet Temp = new C2DLineBaseSetSet(); while (Count > 0) { // pop the last one. C2DLineBaseSet pLast = this[Count - 1]; this.RemoveAt(Count - 1); if (!pLast.IsClosed(true)) { int i = 0; while (i < Count) { if (!this[i].IsClosed(true)) { if (this[i].AddIfCommonEnd(pLast)) { pLast = null; i += Count; // escape } } i++; } } if (pLast != null) { Temp.Add(pLast); } } this.ExtractAllOf(Temp); }
/// <summary> /// Returns the routes (collection of lines and sublines) either inside or outside another /// Given the intersection points. /// </summary> /// <param name="IntPts">The intersection points of this with the other polygon.</param> /// <param name="IntIndexes">The corresponding line indexes.</param> /// <param name="Routes">Output. The routes to get the result.</param> /// <param name="bStartInside">True if this polygon starts inside the other.</param> /// <param name="bRoutesInside">True if we require routes of this polygon inside the other.</param> public void GetRoutes(C2DPointSet IntPts, List <int> IntIndexes, C2DLineBaseSetSet Routes, bool bStartInside, bool bRoutesInside) { // Make sure the intersection indexes and points are the same size. if (IntIndexes.Count != IntPts.Count) { Debug.Assert(false); return; } // Set up a new collection of routes. var NewRoutes = new C2DLineBaseSetSet(); // If the polygon has no points then return. if (_Lines.Count < 1) { return; } // Sort the intersections by index so we can go through them in order. IntPts.SortByIndex(IntIndexes); // Set the inside / outside flag to the same as the start inside / outside flag. var bInside = bStartInside; // If we are inside and want route inside or outside and want routes outside then add a new route. if (bInside == bRoutesInside) { NewRoutes.Add(new C2DLineBaseSet()); } // The current index of the intersects. var usCurrentIntIndex = 0; // cycle through the lines on the polygon. for (var i = 0; i < Lines.Count; i++) { // Set up a list of intersection points on this line only. var IntsOnLine = new C2DPointSet(); // Cycle through all intersections on this line (leaving the usCurrentIntIndex at the next intersected line). while (usCurrentIntIndex < IntIndexes.Count && IntIndexes[usCurrentIntIndex] == i) { // Add a copy of the points on this line that are intersections IntsOnLine.AddCopy(IntPts[usCurrentIntIndex]); usCurrentIntIndex++; } // If the line in question intersects the other poly then we have left / entered. if (IntsOnLine.Count > 0) { var SubLines = new C2DLineBaseSet(); Lines[i].GetSubLines(IntsOnLine, SubLines); while (SubLines.Count > 1) { if (bInside == bRoutesInside) { // We have 1. Left and want route in. OR 2. Entered and want routes out. NewRoutes[NewRoutes.Count - 1].Add(SubLines.ExtractAt(0)); bInside = true ^ bRoutesInside; } else { NewRoutes.Add(new C2DLineBaseSet()); bInside = false ^ bRoutesInside; SubLines.RemoveAt(0); } } if (bInside == bRoutesInside) { NewRoutes[NewRoutes.Count - 1].Add(SubLines.ExtractAt(SubLines.Count - 1)); } else { SubLines.RemoveAt(SubLines.Count - 1); } } // Otherwise, if we are e.g. inside and want routes in the keep adding the end poitn of the line. else if (bInside == bRoutesInside) { NewRoutes[NewRoutes.Count - 1].AddCopy(Lines[i]); } } // Put all the new routes into the provided collection. Routes.ExtractAllOf(NewRoutes); }