/// <summary> /// Returns the centroid. /// </summary> public C2DPoint GetCentroid() { // Find the centroid and area of the straight line polygon. C2DPoint Centroid = new C2DPoint(0, 0); // C2DPoint pti = new C2DPoint(); // C2DPoint ptii; double dArea = 0; for (int i = 0; i < Lines.Count; i++) { C2DPoint pti = Lines[i].GetPointFrom(); C2DPoint ptii = Lines[i].GetPointTo(); Centroid.x += (pti.x + ptii.x) * (pti.x * ptii.y - ptii.x * pti.y); Centroid.y += (pti.y + ptii.y) * (pti.x * ptii.y - ptii.x * pti.y); dArea += pti.x * ptii.y - ptii.x * pti.y; } dArea = dArea / 2.0; Centroid.x = Centroid.x / (6.0 * dArea); Centroid.y = Centroid.y / (6.0 * dArea); List <double> dSegAreas = new List <double>(); double dTotalArea = dArea; List <C2DPoint> SegCentroids = new List <C2DPoint>(); for (int i = 0; i < Lines.Count; i++) { if (Lines[i] is C2DArc) { C2DSegment Seg = new C2DSegment(Lines[i] as C2DArc); double dSegArea = Seg.GetAreaSigned(); dTotalArea += dSegArea; dSegAreas.Add(dSegArea); SegCentroids.Add(Seg.GetCentroid()); } } Centroid.Multiply(dArea); for (int i = 0; i < dSegAreas.Count; i++) { Centroid.x += SegCentroids[i].x * dSegAreas[i]; Centroid.y += SegCentroids[i].y * dSegAreas[i]; } Centroid.Multiply(1 / dTotalArea); return(Centroid); }
/// <summary> /// Returns the centroid. /// </summary> public C2DPoint GetCentroid() { // Find the area first. Do it explicitly as we may need bits of the calc later. var dSegAng = Arc.GetSegmentAngle(); var bBig = Arc.ArcOnRight == Arc.CentreOnRight; var dRadius = Arc.Radius; var dRadiusSquare = dRadius * dRadius; var dCircleArea = dRadiusSquare * Constants.conPI; var dArea = dRadiusSquare * ((dSegAng - Math.Sin(dSegAng)) / 2); // Find the maximum length of the small segment along the direction of the line. var dLength = Arc.Line.GetLength(); // Now find the average height of the segment over that line var dHeight = dArea / dLength; // Find the centre point on the line and the centre of the circle var ptLineCen = new C2DPoint(Arc.Line.GetMidPoint()); var ptCircleCen = new C2DPoint(Arc.GetCircleCentre()); // Set up a line from the mid point on the line to the circle centre // then set the length of it to the average height divided by 2. The end // point of the line is then the centroid. If we are using the small bit, // The line needs to be reversed. var Line = new C2DLine(ptLineCen, ptCircleCen); Line.vector.Reverse(); Line.vector.SetLength(dHeight / 2); if (bBig) { var ptSmallCen = new C2DPoint(Line.GetPointTo()); // Return the weighted average of the 2 centroids. ptCircleCen.Multiply(dCircleArea); ptSmallCen.Multiply(dArea); var pRes = ptCircleCen - ptSmallCen; pRes.Multiply(1.0 / (dCircleArea - dArea)); return(pRes); // return ( new C2DPoint(ptCircleCen * dCircleArea - ptSmallCen * dArea) ) / ( dCircleArea - dArea); } else { return(Line.GetPointTo()); } }
/// <summary> /// Calculates the centroid of the polygon by moving it according to each holes /// weighted centroid. /// </summary> public C2DPoint GetCentroid() { C2DPoint HoleCen = new C2DPoint(0, 0); if (_Holes.Count == 0) { return(Rim.GetCentroid()); } C2DPoint PolyCen = Rim.GetCentroid(); double dPolyArea = Rim.GetArea(); double dHoleArea = 0; for (int i = 0; i < _Holes.Count; i++) { dHoleArea += GetHole(i).GetArea(); } if (dHoleArea == 0 || dHoleArea == dPolyArea) { return(Rim.GetCentroid()); } else { for (int i = 0; i < _Holes.Count; i++) { C2DPoint pt = GetHole(i).GetCentroid(); pt.Multiply(GetHole(i).GetArea() / dHoleArea); HoleCen += pt; } } C2DVector Vec = new C2DVector(HoleCen, PolyCen); Vec.Multiply(dHoleArea / (dPolyArea - dHoleArea)); PolyCen.Move(Vec); return(PolyCen); }
/// <summary> /// Returns the centroid. /// </summary> public C2DPoint GetCentroid() { // Find the centroid and area of the straight line polygon. C2DPoint Centroid = new C2DPoint(0, 0); // C2DPoint pti = new C2DPoint(); // C2DPoint ptii; double dArea = 0; for (int i = 0; i < Lines.Count; i++) { C2DPoint pti = Lines[i].GetPointFrom(); C2DPoint ptii = Lines[i].GetPointTo(); Centroid.x += (pti.x + ptii.x) * (pti.x * ptii.y - ptii.x * pti.y); Centroid.y += (pti.y + ptii.y) * (pti.x * ptii.y - ptii.x * pti.y); dArea += pti.x * ptii.y - ptii.x * pti.y; } dArea = dArea / 2.0; Centroid.x = Centroid.x / (6.0 * dArea); Centroid.y = Centroid.y / (6.0 * dArea); List<double> dSegAreas = new List<double>(); double dTotalArea = dArea; List<C2DPoint> SegCentroids = new List<C2DPoint>(); for (int i = 0; i < Lines.Count; i++) { if (Lines[i] is C2DArc) { C2DSegment Seg = new C2DSegment( Lines[i] as C2DArc ); double dSegArea = Seg.GetAreaSigned(); dTotalArea += dSegArea; dSegAreas.Add( dSegArea ); SegCentroids.Add( Seg.GetCentroid() ); } } Centroid.Multiply( dArea); for (int i = 0; i < dSegAreas.Count; i++) { Centroid.x += SegCentroids[i].x * dSegAreas[i]; Centroid.y += SegCentroids[i].y * dSegAreas[i]; } Centroid.Multiply( 1/ dTotalArea); return Centroid; }
/// <summary> /// Returns the centroid. /// </summary> public C2DPoint GetCentroid() { // Find the area first. Do it explicitly as we may need bits of the calc later. double dSegAng = Arc.GetSegmentAngle(); bool bBig = Arc.ArcOnRight == Arc.CentreOnRight; double dRadius = Arc.Radius; double dRadiusSquare = dRadius * dRadius; double dCircleArea = dRadiusSquare * Constants.conPI; double dArea = dRadiusSquare * ( (dSegAng - Math.Sin(dSegAng)) / 2); // Find the maximum length of the small segment along the direction of the line. double dLength = Arc.Line.GetLength(); // Now find the average height of the segment over that line double dHeight = dArea / dLength; // Find the centre point on the line and the centre of the circle C2DPoint ptLineCen = new C2DPoint(Arc.Line.GetMidPoint()); C2DPoint ptCircleCen = new C2DPoint(Arc.GetCircleCentre()); // Set up a line from the mid point on the line to the circle centre // then set the length of it to the average height divided by 2. The end // point of the line is then the centroid. If we are using the small bit, // The line needs to be reversed. C2DLine Line = new C2DLine( ptLineCen, ptCircleCen); Line.vector.Reverse(); Line.vector.SetLength( dHeight / 2 ); if (bBig) { C2DPoint ptSmallCen = new C2DPoint(Line.GetPointTo()); // Return the weighted average of the 2 centroids. ptCircleCen.Multiply(dCircleArea); ptSmallCen.Multiply(dArea); C2DPoint pRes = ptCircleCen - ptSmallCen; pRes.Multiply(1.0 / (dCircleArea - dArea)); return pRes; // return ( new C2DPoint(ptCircleCen * dCircleArea - ptSmallCen * dArea) ) / ( dCircleArea - dArea); } else return Line.GetPointTo(); }