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);
}
}