/// <summary>
        /// Joins the contiguous segments into one or more PolylineSegment collections.
        /// Start point and end point of each segment are compared  using the specified tolerance.
        /// </summary>
        /// <param name="tol">The tolerance to use while comparing segments startand end points</param>
        /// <returns>A List of PolylineSegmentCollection instances.</returns>
        public List <PolylineSegmentCollection> Join(Tolerance tol)
        {
            List <PolylineSegmentCollection> result = new List <PolylineSegmentCollection>();
            PolylineSegmentCollection        clone  = new PolylineSegmentCollection(_contents);

            while (clone.Count > 0)
            {
                PolylineSegmentCollection newCol = new PolylineSegmentCollection();
                PolylineSegment           seg    = clone[0];
                newCol.Add(seg);
                Point2d start = seg.StartPoint;
                Point2d end   = seg.EndPoint;
                clone.RemoveAt(0);
                while (true)
                {
                    int i = clone.FindIndex(s => s.StartPoint.IsEqualTo(end, tol));
                    if (i >= 0)
                    {
                        seg = clone[i];
                        newCol.Add(seg);
                        end = seg.EndPoint;
                        clone.RemoveAt(i);
                        continue;
                    }
                    i = clone.FindIndex(s => s.EndPoint.IsEqualTo(end, tol));
                    if (i >= 0)
                    {
                        seg = clone[i];
                        seg.Inverse();
                        newCol.Add(seg);
                        end = seg.EndPoint;
                        clone.RemoveAt(i);
                        continue;
                    }
                    i = clone.FindIndex(s => s.EndPoint.IsEqualTo(start, tol));
                    if (i >= 0)
                    {
                        seg = clone[i];
                        newCol.Insert(0, seg);
                        start = seg.StartPoint;
                        clone.RemoveAt(i);
                        continue;
                    }
                    i = clone.FindIndex(s => s.StartPoint.IsEqualTo(start, tol));
                    if (i >= 0)
                    {
                        seg = clone[i];
                        seg.Inverse();
                        newCol.Insert(0, seg);
                        start = seg.StartPoint;
                        clone.RemoveAt(i);
                        continue;
                    }
                    break;
                }
                result.Add(newCol);
            }
            return(result);
        }
예제 #2
0
 /// <summary>
 /// Creates a new Polyline that is the result of projecting the polyline parallel to 'direction' onto 'plane' and returns it.
 /// </summary>
 /// <param name="pline">The polyline (any type) to project.</param>
 /// <param name="plane">The plane onto which the curve is to be projected.</param>
 /// <param name="direction">Direction (in WCS coordinates) of the projection.</param>
 /// <returns>The projected Polyline.</returns>
 internal static Polyline ProjectPolyline(Curve pline, Plane plane, Vector3d direction)
 {
     if (!(pline is Polyline) && !(pline is Polyline2d) && !(pline is Polyline3d))
     {
         return(null);
     }
     plane = new Plane(Point3d.Origin.OrthoProject(plane), direction);
     using (DBObjectCollection oldCol = new DBObjectCollection())
         using (DBObjectCollection newCol = new DBObjectCollection())
         {
             pline.Explode(oldCol);
             foreach (DBObject obj in oldCol)
             {
                 Curve crv = obj as Curve;
                 if (crv != null)
                 {
                     Curve flat = crv.GetProjectedCurve(plane, direction);
                     newCol.Add(flat);
                 }
                 obj.Dispose();
             }
             PolylineSegmentCollection psc = new PolylineSegmentCollection();
             for (int i = 0; i < newCol.Count; i++)
             {
                 if (newCol[i] is Ellipse)
                 {
                     psc.AddRange(new PolylineSegmentCollection((Ellipse)newCol[i]));
                     continue;
                 }
                 Curve   crv   = (Curve)newCol[i];
                 Point3d start = crv.StartPoint;
                 Point3d end   = crv.EndPoint;
                 double  bulge = 0.0;
                 if (crv is Arc)
                 {
                     Arc    arc   = (Arc)crv;
                     double angle = arc.Center.GetVectorTo(start).GetAngleTo(arc.Center.GetVectorTo(end), arc.Normal);
                     bulge = Math.Tan(angle / 4.0);
                 }
                 psc.Add(new PolylineSegment(start.Convert2d(plane), end.Convert2d(plane), bulge));
             }
             foreach (DBObject o in newCol)
             {
                 o.Dispose();
             }
             Polyline projectedPline = psc.Join(new Tolerance(1e-9, 1e-9))[0].ToPolyline();
             projectedPline.Normal    = direction;
             projectedPline.Elevation =
                 plane.PointOnPlane.TransformBy(Matrix3d.WorldToPlane(new Plane(Point3d.Origin, direction))).Z;
             if (!pline.StartPoint.Project(plane, direction).IsEqualTo(projectedPline.StartPoint, new Tolerance(1e-9, 1e-9)))
             {
                 projectedPline.Normal    = direction = direction.Negate();
                 projectedPline.Elevation =
                     plane.PointOnPlane.TransformBy(Matrix3d.WorldToPlane(new Plane(Point3d.Origin, direction))).Z;
             }
             return(projectedPline);
         }
 }
        /// <summary>
        /// Generates a polyline to approximate an ellipse.
        /// </summary>
        /// <param name="ellipse">The ellipse to be approximated</param>
        /// <returns>A new Polyline instance</returns>
        public static Polyline ToPolyline(this Ellipse ellipse)
        {
            Polyline pline = new PolylineSegmentCollection(ellipse).ToPolyline();

            pline.Closed    = ellipse.Closed;
            pline.Normal    = ellipse.Normal;
            pline.Elevation = ellipse.Center.TransformBy(Matrix3d.WorldToPlane(new Plane(Point3d.Origin, ellipse.Normal))).Z;
            return(pline);
        }