Ejemplo n.º 1
0
        /// <summary>
        /// Create another line strip which follows the same path, but avoids tab locations.
        /// NOTE: this currently only works on closed input lines.  The algorithm could
        /// be modified to work correctly with open paths too, but that's not needed yet.
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public LineStrip AvoidTabs(LineStrip input)
        {
            LineStrip ret = new LineStrip();

            foreach (var segment in input.Segments(LineStrip.Type.Closed))
            {
                if (segment.Length < 0.0001f)
                {
                    continue;
                }
                if (segment.A.Z > tabHeight && segment.B.Z > tabHeight)
                {
                    ret.Append(segment.B);
                    continue;
                }
                List <LineSegment> remainingSegments = new List <LineSegment>();
                remainingSegments.Add(segment);
                foreach (Vector3 tab in this.TabLocations)
                {
                    var i = new LineSegmentCircleIntersect(segment, tab, tabRadius + toolRadius);
                    if (i.type == LineSegmentCircleIntersect.IntersectType.Segment)
                    {
                        List <LineSegment> temp = new List <LineSegment>();

                        foreach (var seg in remainingSegments)
                        {
                            temp.AddRange(seg.Subtract(i.IntersectSegment));
                        }
                        remainingSegments = temp;
                    }
                }
                remainingSegments.RemoveAll(s => s.Length < 0.0001f);

                if (remainingSegments.Count == 0)
                {
                    // Entire segment is within a tab
                    TestAddPoint(ClearHeight(segment.B, tabHeight), ret.Vertices);
                }
                else
                {
                    // Everything described in "remainingSegments" is outside of the tab, and the spaces
                    // between are on the tab.  The path between is known since it's always a straight line.
                    remainingSegments.Sort((s1, s2) => (s1.A - segment.A).Length.CompareTo((s2.A - segment.A).Length));
                    foreach (var s in remainingSegments)
                    {
                        TestAddPoint(ClearHeight(s.A, tabHeight), ret.Vertices);
                        TestAddPoint(s.A, ret.Vertices);
                        TestAddPoint(s.B, ret.Vertices);
                        TestAddPoint(ClearHeight(s.B, tabHeight), ret.Vertices);
                    }
                    TestAddPoint(ClearHeight(segment.B, tabHeight), ret.Vertices);
                }
            }

            return(ret);
        }