public IEnumerator GetEnumerator()

in GraphLayout/MSAGL/Core/Geometry/Curves/Polyline.cs [661:852]


        public IEnumerator<Point> GetEnumerator()
        {
#else
        IEnumerator<Point> IEnumerable<Point>.GetEnumerator() {
#endif
            return new PolylineIterator(this);
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator() {
            return new PolylineIterator(this);
        }

        #endregion

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal Polyline ReversePolyline() {
            var ret = new Polyline();
            PolylinePoint pp = EndPoint;
            while (pp.Prev != null) {
                ret.AddPoint(pp.Point);
                pp = pp.Prev;
            }
            ret.AddPoint(StartPoint.Point);
            ret.Closed = Closed;
            return ret;
        }

        internal PolylinePoint Next(PolylinePoint a) {
            return a.Next ?? (Closed ? StartPoint : null);
        }

        internal PolylinePoint Prev(PolylinePoint a) {
            return a.Prev ?? (Closed ? EndPoint : null);
        }

        /// <summary>
        /// creates a polyline from a point enumeration
        /// </summary>
        /// <param name="points"></param>
        public Polyline(IEnumerable<Point> points) {
            ValidateArg.IsNotNull(points, "points");
            foreach (var p in points)
                AddPoint(p);
        }

        /// <summary>
        /// creating a polyline from two points
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "b"),
         SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "a")]
        public Polyline(Point a, Point b) {
            AddPoint(a);
            AddPoint(b);
        }


        /// <summary>
        /// an empty constructor
        /// </summary>
        public Polyline() {}

        ///<summary>
        ///</summary>
        ///<param name="points"></param>
#if SHARPKIT //http://code.google.com/p/sharpkit/issues/detail?id=339
        [SharpKit.JavaScript.JsMethod(NativeParams = false)]
#endif
        public Polyline(params Point[] points) : this((IEnumerable<Point>)points) { }

        /// <summary>
        /// true in general for convex polylines
        /// </summary>
        /// <returns></returns>
        internal bool IsClockwise() {
            return Point.GetTriangleOrientation(StartPoint.Point, StartPoint.Next.Point, StartPoint.Next.Next.Point) ==
                   TriangleOrientation.Clockwise;
        }

        internal void RemoveStartPoint() {
            PolylinePoint p = StartPoint.Next;
            p.Prev = null;
            StartPoint = p;
            RequireInit();
        }

        internal void RemoveEndPoint() {
            PolylinePoint p = EndPoint.Prev;
            p.Next = null;
            EndPoint = p;
            RequireInit();
        }

        /// <summary>
        /// Returns the point location value. The assumption is that the polyline goes clockwise and is closed and convex.
        /// </summary>
        /// <param name="point">Point to find.</param>
        /// <param name="witness">if the point belongs to the boundary then witness is
        ///         the first point of the boundary segment containing p </param>
        /// <returns></returns>
        internal PointLocation GetPointLocation(Point point, out PolylinePoint witness) {
            Debug.Assert(Closed && IsClockwise());
            witness = null;

            foreach (PolylinePoint polyPoint in PolylinePoints) {
                PolylinePoint secondPoint = Next(polyPoint);
                TriangleOrientation triangleOrientation = Point.GetTriangleOrientation(point, polyPoint.Point,
                                                                                       secondPoint.Point);
                if (triangleOrientation == TriangleOrientation.Counterclockwise)
                    return PointLocation.Outside;
                if (triangleOrientation == TriangleOrientation.Collinear)
                    if ((point - polyPoint.Point)*(secondPoint.Point - point) >= 0) {
                        witness = polyPoint;
                        return PointLocation.Boundary;
                    }
            }

            return PointLocation.Inside;
        }

        /// <summary>
        /// Returns the point location value and the edge containing it if it belongs to a boundary. 
        /// The assumption is that the polyline goes clockwise and is closed and convex.
        /// </summary>
        /// <param name="point">Point to find</param>
        /// <param name="edgeStart">The starting point of the boundary hit, if any</param>
        /// <param name="edgeEnd">The ending point of the boundary hit, if any</param>
        /// <returns></returns>
        [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#")]
        [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#")]
        public PointLocation GetPointLocation(Point point, out Point edgeStart, out Point edgeEnd) {
            PolylinePoint start;
            edgeStart = new Point();
            edgeEnd = new Point();
            PointLocation loc = GetPointLocation(point, out start);
            if (PointLocation.Boundary == loc) {
                edgeStart = start.Point;
                edgeEnd = start.NextOnPolyline.Point;
            }
            return loc;
        }

        /// <summary>
        /// shift the given polyline by delta
        /// </summary>
        /// <param name="delta"></param>
        public void Shift(Point delta) {
            for (PolylinePoint pp = StartPoint; pp != null; pp = pp.Next)
                pp.Point += delta;
        }

        #region ICurve Members

        /// <summary>
        /// 
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public double Curvature(double t) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public double CurvatureDerivative(double t) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public double CurvatureSecondDerivative(double t) {
            throw new NotImplementedException();
        }

        #endregion

        internal void AddRangeOfPoints(IEnumerable<Point> points){
            foreach (var point in points)
                AddPoint(point);
        }
    }