예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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());
            }
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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;
        }
예제 #5
0
        /// <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();
        }