public void alignPathsDirectionsWithSource(ref Paths segs, ref Paths sourceSegs) { // The assumption is that a seg in segs will be on only one of the sourceSegs. foreach (Path seg in segs) { if (seg == null || seg.Count < 2) { continue; } IntPoint first = seg[0]; IntPoint second = seg[1]; bool foundSource = false; foreach (Path src in sourceSegs) { // setp through each src line to see if first falls on it. for (int k = 0; k < src.Count - 1; k++) { if (PointOnLineSegment(first, src[k], src[k + 1], true)) { //Debug.Log(first.X + ", "+ first.Y + " on line " + src[k].X + ", " +src[k].Y + "->" +src[k+1].X + ", " + src[k+1].Y); if (AXSegment.pointsAreEqual(second, src[k]) || (Pather.Distance(src[k], second) < Pather.Distance(src[k], first))) { foundSource = true; seg.Reverse(); } break; } } if (foundSource) { break; } } } }
// This is used with rails since the Clipper Lib does not support // difference with the lines of the clip object removed. // In other words, to open a door in a closed polygon, // we use this to remove the edges that were originally on the clip object // leaving only the line segments of the subject that were not inside the clip shape. public Paths assembleRailPathsFromClippedSegments(AXClipperLib.PolyTree solutionRail) { // Take all the clipped segments and connect Paths clippedSegments = Clipper.OpenPathsFromPolyTree(solutionRail); //Debug.Log ("clipped segments " + clippedSegments.Count); //Archimatix.printPaths(clippedSegments); Dictionary <Path, AXSegment> axsegs = new Dictionary <Path, AXSegment>(); foreach (Path p in clippedSegments) { axsegs.Add(p, new AXSegment(p)); } int cc = 0; foreach (Path clipseg in clippedSegments) { //Debug.Log ("PASS["+cc+"] " + AXGeometryTools.Utilities.pathToString(clipseg)); if (axsegs[clipseg].prev != null && axsegs[clipseg].next != null) { //Debug.Log("Already done"); cc++; continue; } int ccc = 0; foreach (Path compseg in clippedSegments) { if (compseg == clipseg) { //Debug.Log("COMP["+cc+"]["+ccc+"] skip same"); ccc++; continue; } //Debug.Log ("COMP["+cc+"]["+ccc+"]"+AXGeometryTools.Utilities.pathToString(clipseg)+ " with "+AXGeometryTools.Utilities.pathToString(compseg)); if (axsegs[clipseg].prev == null && axsegs[compseg].next == null) { if (AXSegment.pointsAreEqual(clipseg[0], compseg[1])) { axsegs[clipseg].prev = axsegs[compseg]; axsegs[compseg].next = axsegs[clipseg]; //Debug.Log ("prev"); } } if (axsegs[clipseg].prev == null && axsegs[compseg].prev == null) { if (AXSegment.pointsAreEqual(clipseg[0], compseg[0])) { compseg.Reverse(); axsegs[clipseg].prev = axsegs[compseg]; axsegs[compseg].next = axsegs[clipseg]; } } if (axsegs[clipseg].next == null && axsegs[compseg].prev == null) { if (AXSegment.pointsAreEqual(clipseg[1], compseg[0])) { axsegs[clipseg].next = axsegs[compseg]; axsegs[compseg].prev = axsegs[clipseg]; } } if (axsegs[clipseg].next == null && axsegs[compseg].next == null) { if (AXSegment.pointsAreEqual(clipseg[1], compseg[1])) { compseg.Reverse(); axsegs[clipseg].next = axsegs[compseg]; axsegs[compseg].prev = axsegs[clipseg]; } } ccc++; } cc++; } // now all segs should be linked. // go through each that has no prev and create new paths... Paths retPaths = new Paths(); foreach (KeyValuePair <Path, AXSegment> item in axsegs) { Path path = item.Key; if (item.Value.prev == null) { // now crawl up the nexts adding pt[1]s AXSegment next = item.Value; while ((next = next.next) != null) { path.Add(next.path[1]); } retPaths.Add(path); } } return(retPaths); }