private bool SegmentIsAllInside(IntPointNode lastAddedNode, IntPointNode crossingNode) { if (OutlineData.DistanceFromOutside == null) { // check just the center point return(OutlineData.PointIsInside((lastAddedNode.Position + crossingNode.Position) / 2) == QTPolygonsExtensions.InsideState.Inside); } else { // check many points along the line return(OutlineData.PointIsInside((lastAddedNode.Position + crossingNode.Position) / 2) == QTPolygonsExtensions.InsideState.Inside && OutlineData.PointIsInside(lastAddedNode.Position + (crossingNode.Position - lastAddedNode.Position) / 4) == QTPolygonsExtensions.InsideState.Inside && OutlineData.PointIsInside(lastAddedNode.Position + (crossingNode.Position - lastAddedNode.Position) * 3 / 4) == QTPolygonsExtensions.InsideState.Inside); } }
private void OptimizePathPoints(Polygon pathThatIsInside) { var testPoints = new List <int>(); for (int i = pathThatIsInside.Count - 2; i >= 1; i--) { testPoints.Add(i); } bool removedSomething; do { removedSomething = false; foreach (var testIndex in testPoints) { var startPosition = pathThatIsInside[testIndex - 1]; var endPosition = pathThatIsInside[testIndex + 1]; var crossings = new List <(int polyIndex, int pointIndex, IntPoint position)>(OutlineData.Polygons.FindCrossingPoints(startPosition, endPosition, OutlineData.EdgeQuadTrees)); bool isCrossingEdge = false; foreach (var(polyIndex, pointIndex, position) in crossings) { if (position != startPosition && position != endPosition) { isCrossingEdge = true; break; } } if (!isCrossingEdge && OutlineData.PointIsInside((startPosition + endPosition) / 2) == QTPolygonsExtensions.InsideState.Inside) { pathThatIsInside.RemoveAt(testIndex); removedSomething = true; } } testPoints.Clear(); for (int i = pathThatIsInside.Count - 2; i >= 1; i--) { testPoints.Add(i); } }while (removedSomething); }
private void OptimizePathPoints(Polygon pathThatIsInside) { for (int startIndex = 0; startIndex < pathThatIsInside.Count - 2; startIndex++) { var startPosition = pathThatIsInside[startIndex]; for (int endIndex = pathThatIsInside.Count - 1; endIndex > startIndex + 1; endIndex--) { var endPosition = pathThatIsInside[endIndex]; var crossings = new List <(int polyIndex, int pointIndex, IntPoint position)>(OutlineData.Polygons.FindCrossingPoints(startPosition, endPosition, OutlineData.EdgeQuadTrees)); bool isCrossingEdge = false; foreach (var(polyIndex, pointIndex, position) in crossings) { if (position != startPosition && position != endPosition) { isCrossingEdge = true; break; } } if (!isCrossingEdge && OutlineData.PointIsInside((startPosition + endPosition) / 2) == QTPolygonsExtensions.InsideState.Inside) { // remove A+1 - B-1 for (int removeIndex = endIndex - 1; removeIndex > startIndex; removeIndex--) { pathThatIsInside.RemoveAt(removeIndex); } endIndex = pathThatIsInside.Count - 1; } } } }
private bool CalculatePath(IntPoint startPointIn, IntPoint endPointIn, Polygon pathThatIsInside, int layerIndex) { double z = startPointIn.Z; startPointIn.Z = 0; endPointIn.Z = 0; if (OutlineData?.Polygons == null || OutlineData?.Polygons.Count == 0) { return(false); } // neither needed to be moved if (OutlineData.Polygons.FindIntersection(startPointIn, endPointIn, OutlineData.EdgeQuadTrees) == Intersection.None && OutlineData.PointIsInside((startPointIn + endPointIn) / 2) == QTPolygonsExtensions.InsideState.Inside) { return(true); } OutlineData.RemovePointList.Dispose(); pathThatIsInside.Clear(); // Check if we are inside the boundaries var lastAddedNode = GetWayPointInside(startPointIn, out IntPointNode startPlanNode); var lastToAddNode = GetWayPointInside(endPointIn, out IntPointNode endPlanNode); long startToEndDistanceSqrd = (endPointIn - startPointIn).LengthSquared(); long moveStartInDistanceSqrd = (startPlanNode.Position - lastAddedNode.Position).LengthSquared(); long moveEndInDistanceSqrd = (endPlanNode.Position - lastToAddNode.Position).LengthSquared(); // if we move both points less than the distance of this segment if (startToEndDistanceSqrd < moveStartInDistanceSqrd && startToEndDistanceSqrd < moveEndInDistanceSqrd) { // then go ahead and say it is a good path return(true); } var crossings = new List <(int polyIndex, int pointIndex, IntPoint position)>(OutlineData.Polygons.FindCrossingPoints(lastAddedNode.Position, lastToAddNode.Position, OutlineData.EdgeQuadTrees)); if (crossings.Count == 0) { return(true); } crossings.Sort(new PolygonAndPointDirectionSorter(lastAddedNode.Position, lastToAddNode.Position)); foreach (var(polyIndex, pointIndex, position) in crossings.SkipSame()) { IntPointNode crossingNode = OutlineData.Waypoints.FindNode(position, FindNodeDist); // for every crossing try to connect it up in the waypoint data if (crossingNode == null) { crossingNode = AddTempWayPoint(OutlineData.RemovePointList, position); // also connect it to the next and prev points on the polygon it came from HookUpToEdge(crossingNode, polyIndex, pointIndex); } if (lastAddedNode != crossingNode && (SegmentIsAllInside(lastAddedNode, crossingNode) || lastAddedNode.Links.Count == 0)) { OutlineData.Waypoints.AddPathLink(lastAddedNode, crossingNode); } else if (crossingNode.Links.Count == 0) { // link it to the edge it is on HookUpToEdge(crossingNode, polyIndex, pointIndex); } lastAddedNode = crossingNode; } if (lastAddedNode != lastToAddNode && (OutlineData.PointIsInside((lastAddedNode.Position + lastToAddNode.Position) / 2) == QTPolygonsExtensions.InsideState.Inside || lastToAddNode.Links.Count == 0)) { // connect the last crossing to the end node OutlineData.Waypoints.AddPathLink(lastAddedNode, lastToAddNode); } Path <IntPointNode> path = OutlineData.Waypoints.FindPath(startPlanNode, endPlanNode, true); foreach (var node in path.Nodes.SkipSamePosition()) { pathThatIsInside.Add(new IntPoint(node.Position, z)); } if (path.Nodes.Length == 0 && saveBadPathToDisk) { WriteErrorForTesting(layerIndex, startPointIn, endPointIn, 0); return(false); } return(true); }
public bool PointIsInsideBoundary(IntPoint intPoint) { return(OutlineData.PointIsInside(intPoint) == QTPolygonsExtensions.InsideState.Inside); }