Пример #1
0
        public IGraphic Extend(double distance, double segmentLength, JointType jointType, IEnumerable <Segment> segments = null)
        {
            var      start   = Start;
            var      end     = End;
            var      vec     = GraphicHelper.GetVector(end - start) * distance;
            IGraphic graphic = new GraphicLine(start + vec, end + vec);

            if (segments != null)
            {
                graphic = new GraphicCompositeCurve(graphic.Spilt(segments, segmentLength), false);
            }
            return(graphic);
        }
Пример #2
0
        internal static IGraphic Extend(IList <Point> points, double distance, JointType jointType, IEnumerable <Segment> segments, bool isClosed)
        {
            var tuples     = new List <Tuple <IGraphic, GeoLine?> >();
            var lastLine   = default(GeoLine?);
            var lastOrigin = default(GeoLine?);
            var index      = 0;

            foreach (var line in GetLines(points, distance, isClosed))
            {
                if (lastLine.HasValue)
                {
                    var beforeOrigin = lastOrigin.Value;
                    var before       = lastLine.Value;
                    var after        = line;
                    var angle        = before.AngleTo(after);
                    if (Utilities.IsZero(Math.Abs(angle)))
                    {
                        tuples.Add(new Tuple <IGraphic, GeoLine?>(new GraphicLine(before.P1, before.P2), beforeOrigin));
                    }
                    else
                    {
                        var flag = Utilities.IsClose(Math.Abs(angle), 180);
                        if (angle < 0 ^ distance > 0)
                        {
                            switch (jointType)
                            {
                            case JointType.Flat:
                            {
                                tuples.Add(new Tuple <IGraphic, GeoLine?>(new GraphicLine(before.P1, before.P2), beforeOrigin));
                                tuples.Add(new Tuple <IGraphic, GeoLine?>(new GraphicLine(before.P2, after.P1), null));
                            }
                            break;

                            case JointType.Sharp:
                            {
                                if (flag)
                                {
                                    return(null);
                                }
                                var cp = before.Cross(after);
                                if (!cp.HasValue)
                                {
                                    return(null);
                                }
                                tuples.Add(new Tuple <IGraphic, GeoLine?>(new GraphicLine(before.P1, cp.Value), beforeOrigin));
                                after = new GeoLine(cp.Value, after.P2);
                            }
                            break;

                            case JointType.Rounded:
                            {
                                tuples.Add(new Tuple <IGraphic, GeoLine?>(new GraphicLine(before.P1, before.P2), beforeOrigin));
                                var center     = points[index];
                                var radius     = Math.Abs(distance);
                                var startV     = before.P2 - center;
                                var endV       = after.P1 - center;
                                var startAngle = Vector.AngleBetween(new Vector(1, 0), startV);
                                var endAngle   = startAngle + Vector.AngleBetween(startV, endV);
                                if (endAngle > startAngle)
                                {
                                    tuples.Add(new Tuple <IGraphic, GeoLine?>(new GraphicArc(center, radius, startAngle, endAngle), null));
                                }
                                else
                                {
                                    tuples.Add(new Tuple <IGraphic, GeoLine?>(new GraphicArc(center, radius, endAngle, startAngle, true), null));
                                }
                            }
                            break;
                            }
                        }
                        else
                        {
                            if (flag)
                            {
                                return(null);
                            }
                            var cp = before.Cross(after);
                            if (cp.HasValue && before.IsOnLine(cp.Value) && after.IsOnLine(cp.Value))
                            {
                                before = new GeoLine(before.P1, cp.Value);
                                after  = new GeoLine(cp.Value, after.P2);
                                tuples.Add(new Tuple <IGraphic, GeoLine?>(new GraphicLine(before.P1, before.P2), beforeOrigin));
                            }
                            else
                            {
                                return(null);
                            }
                        }
                    }
                    lastLine = after;
                }
                else
                {
                    lastLine = line;
                }
                lastOrigin = line;
                index++;
            }
            if (lastLine.HasValue)
            {
                if (!isClosed)
                {
                    tuples.Add(new Tuple <IGraphic, GeoLine?>(new GraphicLine(lastLine.Value.P1, lastLine.Value.P2), lastOrigin));
                }
                else
                {
                    var tuple     = tuples[0];
                    var firstLine = (GraphicLine)tuple.Item1;
                    var p1        = lastLine.Value.P1;
                    var p2        = firstLine.P2;
                    var vec1      = p2 - firstLine.P1;
                    var vec2      = p2 - p1;
                    if (Utilities.IsSameDirection(vec1, vec2))
                    {
                        firstLine = new GraphicLine(p1, p2);
                        tuples[0] = new Tuple <IGraphic, GeoLine?>(firstLine, tuple.Item2);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }

            if (tuples.Count > 0)
            {
                if (segments != null)
                {
                    var graphics = new List <IGraphic>();
                    foreach (var segment in segments)
                    {
                        var started       = false;
                        var subGraphics   = new List <IGraphic>();
                        var currentOffset = 0d;
                        var startOffset   = segment.StartOffset;
                        var endOffset     = segment.EndOffset;
                        foreach (var tuple in tuples)
                        {
                            var item = tuple.Item2;
                            if (item.HasValue)
                            {
                                var line   = item.Value;
                                var offset = currentOffset + line.Length;
                                if (currentOffset < endOffset && offset > startOffset)
                                {
                                    if (currentOffset >= startOffset && offset <= endOffset)
                                    {
                                        subGraphics.Add(tuple.Item1);
                                        started = true;
                                    }
                                    else
                                    {
                                        var brk     = false;
                                        var newLine = (GraphicLine)tuple.Item1;
                                        var sp      = newLine.Start;
                                        var ep      = newLine.End;
                                        if (startOffset > currentOffset)
                                        {
                                            var p = line.GetPoint(startOffset - currentOffset);
                                            if (newLine.IsOnLine(p))
                                            {
                                                sp      = p;
                                                started = true;
                                            }
                                            else
                                            {
                                                var vec1 = newLine.End - p;
                                                var vec2 = newLine.End - newLine.Start;
                                                started = Utilities.IsSameDirection(vec1, vec2);
                                            }
                                        }
                                        else
                                        {
                                            started = true;
                                        }

                                        if (endOffset < offset)
                                        {
                                            var p = line.GetPoint(endOffset - currentOffset);
                                            if (newLine.IsOnLine(p))
                                            {
                                                ep = p;
                                            }
                                            else
                                            {
                                                var vec1 = p - newLine.Start;
                                                var vec2 = newLine.End - newLine.Start;
                                                started = Utilities.IsSameDirection(vec1, vec2);
                                            }
                                            brk = true;
                                        }

                                        if (started)
                                        {
                                            subGraphics.Add(new GraphicLine(sp, ep));
                                        }
                                        if (brk)
                                        {
                                            break;
                                        }
                                    }
                                }
                                else if (currentOffset >= endOffset)
                                {
                                    if (subGraphics.Count > 0)
                                    {
                                        graphics.Add(new GraphicCompositeCurve(subGraphics, true));
                                    }
                                    break;
                                }
                                currentOffset = offset;
                            }
                            else if (started)
                            {
                                subGraphics.Add(tuple.Item1);
                            }
                        }
                        if (subGraphics.Count > 0)
                        {
                            graphics.Add(new GraphicCompositeCurve(subGraphics, true));
                        }
                    }
                    if (graphics.Count > 0)
                    {
                        return(new GraphicCompositeCurve(graphics, false));
                    }
                }
                else
                {
                    return(new GraphicCompositeCurve(tuples.Select(graphic => graphic.Item1), true));
                }
            }
            return(null);
        }