public bool CreatePathInsideBoundary(IntPoint startPoint, IntPoint endPoint, List <IntPoint> pathThatIsInside) { if (saveDebugData) { using (StreamWriter sw = File.AppendText("test.txt")) { if (boundry) { string pointsString = bounderyPolygons.WriteToString(); sw.WriteLine(pointsString); } sw.WriteLine(startPoint.ToString() + " " + endPoint.ToString()); } } if ((endPoint - startPoint).ShorterThen(1500)) { // If the movement is very short (not a lot of time to ooze filament) // then don't add any points return(true); } bool addEndpoint = false; //Check if we are inside the comb boundaries if (!PointIsInsideBoundary(startPoint)) { if (!MovePointInsideBoundary(ref startPoint)) { //If we fail to move the point inside the comb boundary we need to retract. return(false); } pathThatIsInside.Add(startPoint); } if (!PointIsInsideBoundary(endPoint)) { if (!MovePointInsideBoundary(ref endPoint)) { //If we fail to move the point inside the comb boundary we need to retract. return(false); } addEndpoint = true; } // Check if we are crossing any bounderies if (!DoesLineCrossBoundery(startPoint, endPoint)) { //We're not crossing any boundaries. So skip the comb generation. if (!addEndpoint && pathThatIsInside.Count == 0) { //Only skip if we didn't move the start and end point. return(true); } } // Calculate the matrix to change points so they are in the direction of the line segment. { IntPoint diff = endPoint - startPoint; lineToSameYMatrix = new PointMatrix(diff); this.rotatedStartPoint = lineToSameYMatrix.apply(startPoint); this.rotatedEndPoint = lineToSameYMatrix.apply(endPoint); } // Calculate the minimum and maximum positions where we cross the comb boundary CalcMinMax(); long nomalizedStartX = rotatedStartPoint.X; List <IntPoint> pointList = new List <IntPoint>(); // Now walk trough the crossings, for every boundary we cross, find the initial cross point and the exit point. // Then add all the points in between to the pointList and continue with the next boundary we will cross, // until there are no more boundaries to cross. // This gives a path from the start to finish curved around the holes that it encounters. while (true) { // if we go up enough we should run into the boundry int abovePolyIndex = GetPolygonIndexAbove(nomalizedStartX); if (abovePolyIndex < 0) { break; } pointList.Add(lineToSameYMatrix.unapply(new IntPoint(minXPosition[abovePolyIndex] - 200, rotatedStartPoint.Y))); if ((indexOfMinX[abovePolyIndex] - indexOfMaxX[abovePolyIndex] + bounderyPolygons[abovePolyIndex].Count) % bounderyPolygons[abovePolyIndex].Count > (indexOfMaxX[abovePolyIndex] - indexOfMinX[abovePolyIndex] + bounderyPolygons[abovePolyIndex].Count) % bounderyPolygons[abovePolyIndex].Count) { for (int i = indexOfMinX[abovePolyIndex]; i != indexOfMaxX[abovePolyIndex]; i = (i < bounderyPolygons[abovePolyIndex].Count - 1) ? (i + 1) : (0)) { pointList.Add(GetBounderyPointWithOffset(abovePolyIndex, i)); } } else { indexOfMinX[abovePolyIndex]--; if (indexOfMinX[abovePolyIndex] == -1) { indexOfMinX[abovePolyIndex] = bounderyPolygons[abovePolyIndex].Count - 1; } indexOfMaxX[abovePolyIndex]--; if (indexOfMaxX[abovePolyIndex] == -1) { indexOfMaxX[abovePolyIndex] = bounderyPolygons[abovePolyIndex].Count - 1; } for (int i = indexOfMinX[abovePolyIndex]; i != indexOfMaxX[abovePolyIndex]; i = (i > 0) ? (i - 1) : (bounderyPolygons[abovePolyIndex].Count - 1)) { pointList.Add(GetBounderyPointWithOffset(abovePolyIndex, i)); } } pointList.Add(lineToSameYMatrix.unapply(new IntPoint(maxXPosition[abovePolyIndex] + 200, rotatedStartPoint.Y))); nomalizedStartX = maxXPosition[abovePolyIndex]; } pointList.Add(endPoint); if (addEndpoint) { pointList.Add(endPoint); } #if false // Optimize the pointList, skip each point we could already reach by connecting directly to the next point. for (int startIndex = 0; startIndex < pointList.Count - 2; startIndex++) { IntPoint startPosition = pointList[startIndex]; // make sure there is at least one point between the start and the end to optomize if (pointList.Count > startIndex + 2) { for (int checkIndex = pointList.Count - 1; checkIndex > startIndex + 1; checkIndex--) { IntPoint checkPosition = pointList[checkIndex]; if (!DoesLineCrossBoundery(startPosition, checkPosition)) { // Remove all the points from startIndex+1 to checkIndex-1, inclusive. for (int i = startIndex + 1; i < checkIndex; i++) { pointList.RemoveAt(startIndex + 1); } // we removed all the points up to start so we are done with the inner loop break; } } } } #endif foreach (IntPoint point in pointList) { pathThatIsInside.Add(point); } return(true); }
public bool CreatePathInsideBoundary(IntPoint startPoint, IntPoint endPoint, List<IntPoint> pathThatIsInside) { if (saveDebugData) { using (StreamWriter sw = File.AppendText("test.txt")) { if (boundry) { string pointsString = bounderyPolygons.WriteToString(); sw.WriteLine(pointsString); } sw.WriteLine(startPoint.ToString() + " " + endPoint.ToString()); } } if ((endPoint - startPoint).ShorterThen(1500)) { // If the movement is very short (not a lot of time to ooze filament) // then don't add any points return true; } bool addEndpoint = false; //Check if we are inside the comb boundaries if (!PointIsInsideBoundary(startPoint)) { if (!MovePointInsideBoundary(ref startPoint)) { //If we fail to move the point inside the comb boundary we need to retract. return false; } pathThatIsInside.Add(startPoint); } if (!PointIsInsideBoundary(endPoint)) { if (!MovePointInsideBoundary(ref endPoint)) { //If we fail to move the point inside the comb boundary we need to retract. return false; } addEndpoint = true; } // Check if we are crossing any bounderies if (!DoesLineCrossBoundery(startPoint, endPoint)) { //We're not crossing any boundaries. So skip the comb generation. if (!addEndpoint && pathThatIsInside.Count == 0) { //Only skip if we didn't move the start and end point. return true; } } // Calculate the matrix to change points so they are in the direction of the line segment. { IntPoint diff = endPoint - startPoint; lineToSameYMatrix = new PointMatrix(diff); this.rotatedStartPoint = lineToSameYMatrix.apply(startPoint); this.rotatedEndPoint = lineToSameYMatrix.apply(endPoint); } // Calculate the minimum and maximum positions where we cross the comb boundary CalcMinMax(); long nomalizedStartX = rotatedStartPoint.X; List<IntPoint> pointList = new List<IntPoint>(); // Now walk trough the crossings, for every boundary we cross, find the initial cross point and the exit point. // Then add all the points in between to the pointList and continue with the next boundary we will cross, // until there are no more boundaries to cross. // This gives a path from the start to finish curved around the holes that it encounters. while (true) { // if we go up enough we should run into the boundry int abovePolyIndex = GetPolygonIndexAbove(nomalizedStartX); if (abovePolyIndex < 0) { break; } pointList.Add(lineToSameYMatrix.unapply(new IntPoint(minXPosition[abovePolyIndex] - 200, rotatedStartPoint.Y))); if ((indexOfMinX[abovePolyIndex] - indexOfMaxX[abovePolyIndex] + bounderyPolygons[abovePolyIndex].Count) % bounderyPolygons[abovePolyIndex].Count > (indexOfMaxX[abovePolyIndex] - indexOfMinX[abovePolyIndex] + bounderyPolygons[abovePolyIndex].Count) % bounderyPolygons[abovePolyIndex].Count) { for (int i = indexOfMinX[abovePolyIndex]; i != indexOfMaxX[abovePolyIndex]; i = (i < bounderyPolygons[abovePolyIndex].Count - 1) ? (i + 1) : (0)) { pointList.Add(GetBounderyPointWithOffset(abovePolyIndex, i)); } } else { indexOfMinX[abovePolyIndex]--; if (indexOfMinX[abovePolyIndex] == -1) { indexOfMinX[abovePolyIndex] = bounderyPolygons[abovePolyIndex].Count - 1; } indexOfMaxX[abovePolyIndex]--; if (indexOfMaxX[abovePolyIndex] == -1) { indexOfMaxX[abovePolyIndex] = bounderyPolygons[abovePolyIndex].Count - 1; } for (int i = indexOfMinX[abovePolyIndex]; i != indexOfMaxX[abovePolyIndex]; i = (i > 0) ? (i - 1) : (bounderyPolygons[abovePolyIndex].Count - 1)) { pointList.Add(GetBounderyPointWithOffset(abovePolyIndex, i)); } } pointList.Add(lineToSameYMatrix.unapply(new IntPoint(maxXPosition[abovePolyIndex] + 200, rotatedStartPoint.Y))); nomalizedStartX = maxXPosition[abovePolyIndex]; } pointList.Add(endPoint); if (addEndpoint) { pointList.Add(endPoint); } #if false // Optimize the pointList, skip each point we could already reach by connecting directly to the next point. for (int startIndex = 0; startIndex < pointList.Count - 2; startIndex++) { IntPoint startPosition = pointList[startIndex]; // make sure there is at least one point between the start and the end to optomize if (pointList.Count > startIndex + 2) { for (int checkIndex = pointList.Count - 1; checkIndex > startIndex + 1; checkIndex--) { IntPoint checkPosition = pointList[checkIndex]; if (!DoesLineCrossBoundery(startPosition, checkPosition)) { // Remove all the points from startIndex+1 to checkIndex-1, inclusive. for (int i = startIndex + 1; i < checkIndex; i++) { pointList.RemoveAt(startIndex + 1); } // we removed all the points up to start so we are done with the inner loop break; } } } } #endif foreach (IntPoint point in pointList) { pathThatIsInside.Add(point); } return true; }