BuildingCoder.CmdSlabBoundaryArea.GetSignedPolygonArea C# (CSharp) Метод

GetSignedPolygonArea() публичный статический Метод

Use the formula area = sign * 0.5 * sum( xi * ( yi+1 - yi-1 ) ) to determine the winding direction (clockwise or counter) and area of a 2D polygon. Cf. also GetPolygonPlane.
public static GetSignedPolygonArea ( List p ) : double
p List
Результат double
        public static double GetSignedPolygonArea( List<UV> p )
        {
            int n = p.Count;
              double sum = p[0].U * ( p[1].V - p[n - 1].V ); // loop at beginning
              for( int i = 1; i < n - 1; ++i )
              {
            sum += p[i].U * ( p[i + 1].V - p[i - 1].V );
              }
              sum += p[n - 1].U * ( p[0].V - p[n - 2].V ); // loop at end
              return 0.5 * sum;
        }

Usage Example

        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app   = commandData.Application;
            UIDocument    uidoc = app.ActiveUIDocument;
            Document      doc   = uidoc.Document;

            List <Element> walls = new List <Element>();

            if (!Util.GetSelectedElementsOrAll(
                    walls, uidoc, typeof(Wall)))
            {
                Selection sel = uidoc.Selection;
                message = (0 < sel.GetElementIds().Count)
          ? "Please select some wall elements."
          : "No wall elements found.";
                return(Result.Failed);
            }

            Options opt = app.Application.Create.NewGeometryOptions();

            List <List <XYZ> > polygons
                = CmdWallProfile.GetWallProfilePolygons(
                      walls, opt);

            int i = 0, n = polygons.Count;

            double[] areas = new double[n];
            double   d, a, maxArea = 0.0;
            XYZ      normal;

            foreach (List <XYZ> polygon in polygons)
            {
                GetPolygonPlane(polygon,
                                out normal, out d, out a);
                if (Math.Abs(maxArea) < Math.Abs(a))
                {
                    maxArea = a;
                }
                areas[i++] = a;

#if DEBUG
                // transform the 3D polygon into a horizontal plane
                // so we can use the 2D GetSignedPolygonArea() and
                // compare its results with the 3D calculation.

                // todo: compare the relative speed of
                // transforming 3d to 2d and using 2d area
                // calculation versus direct 3d area calculation.


                Transform t = GetTransformToZ(normal);

                List <XYZ> polygonHorizontal
                    = ApplyTransform(polygon, t);

                List <UV> polygon2d
                    = CmdSlabBoundaryArea.Flatten(
                          polygonHorizontal);

                double a2
                    = CmdSlabBoundaryArea.GetSignedPolygonArea(
                          polygon2d);

                Debug.Assert(Util.IsEqual(a, a2),
                             "expected same area from 2D and 3D calculations");
#endif
            }

            Debug.Print(
                "{0} boundary loop{1} found.",
                n, Util.PluralSuffix(n));

            for (i = 0; i < n; ++i)
            {
                Debug.Print(
                    "  Loop {0} area is {1} square feet{2}",
                    i,
                    Util.RealString(areas[i]),
                    (areas[i].Equals(maxArea)
            ? ", outer loop of largest wall"
            : ""));
            }

            Creator creator = new Creator(doc);

            using (Transaction tx = new Transaction(doc))
            {
                tx.Start("Draw wall profile loops");
                creator.DrawPolygons(polygons);
                tx.Commit();
            }
            return(Result.Succeeded);
        }