/// <summary> /// Gets the centroid of the polyline. /// </summary> /// <param name="pl">The instance to which the method applies.</param> /// <returns>The centroid of the polyline (OCS coordinates).</returns> public static Point2d Centroid2d([NotNull] this Polyline pl) { var cen = new Point2d(); var tri = new Triangle2d(); CircularArc2d arc; double tmpArea; var area = 0.0; var last = pl.NumberOfVertices - 1; var p0 = pl.GetPoint2dAt(0); var bulge = pl.GetBulgeAt(0); var pts = new List <Point2d> { p0 }; if (Math.Abs(bulge) > 0.0001) { arc = pl.GetArcSegment2dAt(0); area = arc.AlgebricArea(); cen = arc.Centroid() * area; } for (var i = 1; i < last; i++) { var pi = pl.GetPoint2dAt(i); pi.AddTo(pts); tri.Set(p0, pi, pl.GetPoint2dAt(i + 1)); tmpArea = tri.AlgebricArea; cen += (tri.Centroid * tmpArea).GetAsVector(); area += tmpArea; bulge = pl.GetBulgeAt(i); if (Math.Abs(bulge) > 0.0001) { arc = pl.GetArcSegment2dAt(i); tmpArea = arc.AlgebricArea(); area += tmpArea; cen += (arc.Centroid() * tmpArea).GetAsVector(); } } bulge = pl.GetBulgeAt(last); if (Math.Abs(bulge) > 0.0001 && pl.Closed) { arc = pl.GetArcSegment2dAt(last); tmpArea = arc.AlgebricArea(); area += tmpArea; cen += (arc.Centroid() * tmpArea).GetAsVector(); } if (Math.Abs(area) < 0.0001) { // Средняя точка из всех точек полилинии return(new Point2d(pts.Average(a => a.X), pts.Average(a => a.Y))); } return(cen.DivideBy(area)); }
/// <summary> /// Gets the centroid of the polyline 2d. /// </summary> /// <param name="pl">The instance to which the method applies.</param> /// <returns>The centroid of the polyline 2d (WCS coordinates).</returns> public static Point3d Centroid([NotNull] this Polyline2d pl) { var vertices = pl.GetVertices().ToArray(); var last = vertices.Length - 1; var vertex = vertices[0]; var p0 = vertex.Position.Convert2d(); var cen = new Point2d(0.0, 0.0); var area = 0.0; var bulge = vertex.Bulge; double tmpArea; Point2d tmpPt; var tri = new Triangle2d(); CircularArc2d arc; if (Math.Abs(bulge) > 0.0001) { arc = pl.GetArcSegment2dAt(0); tmpArea = arc.AlgebricArea(); tmpPt = arc.Centroid(); area += tmpArea; cen += (new Point2d(tmpPt.X, tmpPt.Y) * tmpArea).GetAsVector(); } for (var i = 1; i < last; i++) { var p1 = vertices[i].Position.Convert2d(); var p2 = vertices[i + 1].Position.Convert2d(); tri.Set(p0, p1, p2); tmpArea = tri.AlgebricArea; area += tmpArea; cen += (tri.Centroid * tmpArea).GetAsVector(); bulge = vertices[i].Bulge; if (Math.Abs(bulge) > 0.0001) { arc = pl.GetArcSegment2dAt(i); tmpArea = arc.AlgebricArea(); tmpPt = arc.Centroid(); area += tmpArea; cen += (new Point2d(tmpPt.X, tmpPt.Y) * tmpArea).GetAsVector(); } } bulge = vertices[last].Bulge; if (Math.Abs(bulge) > 0.0001 && pl.Closed) { arc = pl.GetArcSegment2dAt(last); tmpArea = arc.AlgebricArea(); tmpPt = arc.Centroid(); area += tmpArea; cen += (new Point2d(tmpPt.X, tmpPt.Y) * tmpArea).GetAsVector(); } cen = cen.DivideBy(area); return(new Point3d(cen.X, cen.Y, pl.Elevation).TransformBy(Matrix3d.PlaneToWorld(pl.Normal))); }