示例#1
0
        /// <summary>
        /// Calculate the area enclosed by this curve, were the start and end points to be
        /// joined by a straight line segment.
        /// A plane may optionally be specified, otherwise by default the projected area on
        /// the XY plane will be used.
        /// </summary>
        /// <param name="centroid">Output.  The centroid of the enclosed area, in local coordinates
        /// on the specified plane.</param>
        /// <param name="onPlane">The plane to use to calculate the area.
        /// If not specified, the XY plane will be used.</param>
        /// <returns>The signed area enclosed by this curve on the specified plane,
        /// as a double.</returns>
        public override double CalculateEnclosedArea(out Vector centroid, Plane onPlane = null)
        {
            double result = 0;

            centroid = Vector.Zero;
            for (int i = 0; i < SubCurves.Count; i++)
            {
                Curve  subCrv = SubCurves[i];
                Vector start  = subCrv.StartPoint;
                Vector end    = subCrv.EndPoint;
                if (onPlane != null)
                {
                    start = onPlane.GlobalToLocal(start);
                    end   = onPlane.GlobalToLocal(end);
                }
                double areaUnder = MathsHelper.AreaUnder(start.X, start.Y, end.X, end.Y, ref centroid);
                result += areaUnder;
                Vector subCentroid;
                double subArea = subCrv.CalculateEnclosedArea(out subCentroid, onPlane);
                result   += subArea;
                centroid += subCentroid * subArea;
            }
            centroid /= result;
            return(result);
        }
示例#2
0
        public override double CalculateEnclosedIxx(Plane onPlane = null)
        {
            if (Circle != null)
            {
                if (Closed)
                {
                    Vector localO = onPlane.GlobalToLocal(Circle.Origin);
                    double Io     = (Math.PI / 4) * Circle.Radius.Power(4);
                    Vector v;
                    double area    = CalculateEnclosedArea(out v, onPlane);
                    double yCentre = localO.Y;
                    return(Io + area * yCentre.Squared());
                }
                else
                {
                    Vector origin = Circle.Origin;
                    double radius = Circle.Radius;
                    Vector centroid;
                    double area = CalculateEnclosedArea(out centroid, onPlane).Abs();

                    Plane  oSys   = new Plane(onPlane, origin);
                    Vector localS = oSys.GlobalToLocal(StartPoint);
                    Vector localE = oSys.GlobalToLocal(EndPoint);
                    Vector localM = oSys.GlobalToLocal(Vertices[1].Position);
                    Vector localC = oSys.GlobalToLocal(centroid);

                    Angle  toS  = localS.Angle;
                    Angle  toE  = localE.Angle;
                    Angle  toM  = localM.Angle;
                    double IxxS = SectorIxx(toS, radius);
                    double IxxE = SectorIxx(toE, radius);

                    double IxxTri = Math.Abs((localS.Y.Squared() + localS.Y * localE.Y + localE.Y.Squared()) * (localS.X * localE.Y - localE.X * localS.Y) / 12);

                    double result;
                    if (toM > Math.Min(toS, toE) && toM < Math.Max(toS, toE))
                    {
                        result = Math.Max(IxxS, IxxE) - Math.Min(IxxS, IxxE);
                    }
                    else
                    {
                        result = (Math.PI / 4) * radius.Power(4) - Math.Max(IxxS, IxxE) + Math.Min(IxxS, IxxE);
                    }

                    if (RadianMeasure.IsReflex)
                    {
                        result += IxxTri;
                    }
                    else
                    {
                        result -= IxxTri;
                    }

                    // Adjust for centroid offset:
                    double yC = onPlane.GlobalToLocal(centroid).Y;
                    result += area * (yC.Squared() - localC.Y.Squared());

                    return(result);
                }
            }
            return(0);
        }