/// <summary> /// Creates a new instance of PolylineSegmentCollection from an Ellipse. /// </summary> /// <param name="ellipse">An Ellipse instance.</param> public PolylineSegmentCollection(Ellipse ellipse) { // PolylineSegmentCollection figuring the closed ellipse double pi = Math.PI; Plane plane = new Plane(Point3d.Origin, ellipse.Normal); Point3d cen3d = ellipse.Center; Point3d pt3d0 = cen3d + ellipse.MajorAxis; Point3d pt3d4 = cen3d + ellipse.MinorAxis; Point3d pt3d2 = ellipse.GetPointAtParameter(pi / 4.0); Point2d cen = cen3d.Convert2d(plane); Point2d pt0 = pt3d0.Convert2d(plane); Point2d pt2 = pt3d2.Convert2d(plane); Point2d pt4 = pt3d4.Convert2d(plane); Line2d line01 = new Line2d(pt0, (pt4 - cen).GetNormal() + (pt2 - pt0).GetNormal()); Line2d line21 = new Line2d(pt2, (pt0 - pt4).GetNormal() + (pt0 - pt2).GetNormal()); Line2d line23 = new Line2d(pt2, (pt4 - pt0).GetNormal() + (pt4 - pt2).GetNormal()); Line2d line43 = new Line2d(pt4, (pt0 - cen).GetNormal() + (pt2 - pt4).GetNormal()); Line2d majAx = new Line2d(cen, pt0); Line2d minAx = new Line2d(cen, pt4); Point2d pt1 = line01.IntersectWith(line21)[0]; Point2d pt3 = line23.IntersectWith(line43)[0]; Point2d pt5 = pt3.TransformBy(Matrix2d.Mirroring(minAx)); Point2d pt6 = pt2.TransformBy(Matrix2d.Mirroring(minAx)); Point2d pt7 = pt1.TransformBy(Matrix2d.Mirroring(minAx)); Point2d pt8 = pt0.TransformBy(Matrix2d.Mirroring(minAx)); Point2d pt9 = pt7.TransformBy(Matrix2d.Mirroring(majAx)); Point2d pt10 = pt6.TransformBy(Matrix2d.Mirroring(majAx)); Point2d pt11 = pt5.TransformBy(Matrix2d.Mirroring(majAx)); Point2d pt12 = pt4.TransformBy(Matrix2d.Mirroring(majAx)); Point2d pt13 = pt3.TransformBy(Matrix2d.Mirroring(majAx)); Point2d pt14 = pt2.TransformBy(Matrix2d.Mirroring(majAx)); Point2d pt15 = pt1.TransformBy(Matrix2d.Mirroring(majAx)); double bulge1 = Math.Tan((pt4 - cen).GetAngleTo(pt1 - pt0) / 2.0); double bulge2 = Math.Tan((pt1 - pt2).GetAngleTo(pt0 - pt4) / 2.0); double bulge3 = Math.Tan((pt4 - pt0).GetAngleTo(pt3 - pt2) / 2.0); double bulge4 = Math.Tan((pt3 - pt4).GetAngleTo(pt0 - cen) / 2.0); _contents.Add(new PolylineSegment(pt0, pt1, bulge1)); _contents.Add(new PolylineSegment(pt1, pt2, bulge2)); _contents.Add(new PolylineSegment(pt2, pt3, bulge3)); _contents.Add(new PolylineSegment(pt3, pt4, bulge4)); _contents.Add(new PolylineSegment(pt4, pt5, bulge4)); _contents.Add(new PolylineSegment(pt5, pt6, bulge3)); _contents.Add(new PolylineSegment(pt6, pt7, bulge2)); _contents.Add(new PolylineSegment(pt7, pt8, bulge1)); _contents.Add(new PolylineSegment(pt8, pt9, bulge1)); _contents.Add(new PolylineSegment(pt9, pt10, bulge2)); _contents.Add(new PolylineSegment(pt10, pt11, bulge3)); _contents.Add(new PolylineSegment(pt11, pt12, bulge4)); _contents.Add(new PolylineSegment(pt12, pt13, bulge4)); _contents.Add(new PolylineSegment(pt13, pt14, bulge3)); _contents.Add(new PolylineSegment(pt14, pt15, bulge2)); _contents.Add(new PolylineSegment(pt15, pt0, bulge1)); // if the ellipse is an elliptical arc: if (!ellipse.Closed) { double startParam, endParam; Point2d startPoint = ellipse.StartPoint.Convert2d(plane); Point2d endPoint = ellipse.EndPoint.Convert2d(plane); // index of the PolylineSegment closest to the ellipse start point int startIndex = GetClosestSegmentIndexTo(startPoint); // start point on the PolylineSegment Point2d pt = _contents[startIndex].ToCurve2d().GetClosestPointTo(startPoint).Point; // if the point is equal to the PolylineSegment end point, jump the next segment in collection if (pt.IsEqualTo(_contents[startIndex].EndPoint)) { if (startIndex == 15) { startIndex = 0; } else { startIndex++; } startParam = 0.0; } // else get the 'parameter' at point on the PolylineSegment else { startParam = _contents[startIndex].GetParameterOf(pt); } // index of the PolylineSegment closest to the ellipse end point int endIndex = GetClosestSegmentIndexTo(endPoint); // end point on the PolylineSegment pt = _contents[endIndex].ToCurve2d().GetClosestPointTo(endPoint).Point; // if the point is equals to the PolylineSegment startPoint, jump to the previous segment if (pt.IsEqualTo(_contents[endIndex].StartPoint)) { if (endIndex == 0) { endIndex = 15; } else { endIndex--; } endParam = 1.0; } // else get the 'parameter' at point on the PolylineSegment else { endParam = _contents[endIndex].GetParameterOf(pt); } // if the parameter at start point is not equal to 0.0, calculate the bulge if (startParam != 0.0) { _contents[startIndex].StartPoint = startPoint; _contents[startIndex].Bulge = _contents[startIndex].Bulge * (1.0 - startParam); } // if the parameter at end point is not equal to 1.0, calculate the bulge if (endParam != 1.0) //(endParam != 0.0) { _contents[endIndex].EndPoint = endPoint; _contents[endIndex].Bulge = _contents[endIndex].Bulge * (endParam); } // if both points are on the same segment if (startIndex == endIndex) { PolylineSegment segment = _contents[startIndex]; _contents.Clear(); _contents.Add(segment); } else if (startIndex < endIndex) { _contents.RemoveRange(endIndex + 1, 15 - endIndex); _contents.RemoveRange(0, startIndex); } else { _contents.AddRange(_contents.GetRange(0, endIndex + 1)); _contents.RemoveRange(0, startIndex); } } }