Exemple #1
0
        public static BHE.Panel OffsetOpening(BHE.Panel panel)
        {
            BHE.Panel energyPlusPanel = new BHE.Panel();
            //Checking if there are openings
            if (panel.Openings.Count == 0)
            {
                return(panel);
            }
            else
            {
                //OpeningArea
                List <BHE.Opening> openings          = panel.Openings;
                List <double>      openingAreas      = new List <double>();
                List <PolyCurve>   openingPolyCurves = new List <PolyCurve>();
                foreach (BHE.Opening opening in panel.Openings)
                {
                    List <ICurve> openingCrvs    = opening.Edges.Select(x => x.Curve).ToList();
                    PolyCurve     openingOutline = BH.Engine.Geometry.Create.PolyCurve(openingCrvs);
                    double        openingArea    = openingOutline.Area();
                    openingAreas.Add(openingArea);
                    openingPolyCurves.Add(openingOutline);
                }
                double totalOpeningArea = openingAreas.Sum();

                //PanelArea
                List <ICurve> panelCrvs    = panel.ExternalEdges.Select(x => x.Curve).ToList();
                PolyCurve     panelOutline = BH.Engine.Geometry.Create.PolyCurve(panelCrvs);
                double        panelArea    = panelOutline.Area();

                //Comparing the total opening area to the panel area, if equal: reduce the area of the opening(s).
                if (totalOpeningArea != panelArea)
                {
                    return(panel);
                }
                else
                {
                    List <BH.oM.Geometry.Polyline>         openingPolylines = new List <BH.oM.Geometry.Polyline>();
                    List <List <BH.oM.Geometry.Polyline> > offsetPolylines  = new List <List <BH.oM.Geometry.Polyline> >();
                    List <BHE.Opening> newOpenings = new List <BHE.Opening>();
                    double             distance    = new double();
                    distance = -0.01;
                    panel.Openings.Clear();
                    foreach (BH.oM.Geometry.PolyCurve openingPolyCurve in openingPolyCurves)
                    {
                        List <BH.oM.Geometry.Point> polyPoints      = openingPolyCurve.IDiscontinuityPoints();
                        BH.oM.Geometry.Polyline     openingPolyLine = BH.Engine.Geometry.Create.Polyline(polyPoints);
                        Polyline        offsetPolyline = Geometry.Modify.Offset(openingPolyLine, distance);
                        List <BHE.Edge> edges          = offsetPolyline.ToEdges().ToList();
                        BHE.Opening     newOpening     = new BHE.Opening()
                        {
                            Edges = edges
                        };
                        panel.Openings.Add(newOpening);
                    }
                    return(panel);
                }
            }
        }
Exemple #2
0
        /***************************************************/

        public static Point Centroid(this PolyCurve curve)
        {
            if (!curve.IsPlanar())
            {
                Reflection.Compute.RecordError("Input must be planar.");
                return(null);
            }
            else if (!curve.IsClosed())
            {
                Reflection.Compute.RecordError("Curve is not closed.");
                return(null);
            }
            else if (curve.IsSelfIntersecting())
            {
                Reflection.Compute.RecordWarning("Curve is self intersecting");
                return(null);
            }

            List <ICurve> curveSubParts = curve.SubParts();

            List <Point> pts = new List <Point> {
                curveSubParts[0].IStartPoint()
            };

            foreach (ICurve crv in curveSubParts)
            {
                if (crv is Line)
                {
                    pts.Add((crv as Line).End);
                }
                else if (crv is Arc)
                {
                    pts.Add(crv.IEndPoint());
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            double xc, yc, zc;
            double xc0 = 0, yc0 = 0, zc0 = 0;

            Vector normal = Normal(curve);

            Point pA  = pts[0];
            Point pB0 = pts[1];
            Point pC0 = pts[2];

            Vector firstNormal;

            firstNormal = CrossProduct(pB0 - pA, pC0 - pA);

            Boolean dir = DotProduct(normal, firstNormal) > 0;

            for (int i = 1; i < pts.Count - 2; i++)
            {
                Point pB = pts[i];
                Point pC = pts[i + 1];

                double triangleArea = Area(pB - pA, pC - pA);

                if (DotProduct(CrossProduct(pB - pA, pC - pA), firstNormal) > 0)
                {
                    xc0 += ((pA.X + pB.X + pC.X) / 3) * triangleArea;
                    yc0 += ((pA.Y + pB.Y + pC.Y) / 3) * triangleArea;
                    zc0 += ((pA.Z + pB.Z + pC.Z) / 3) * triangleArea;
                }
                else
                {
                    xc0 -= ((pA.X + pB.X + pC.X) / 3) * triangleArea;
                    yc0 -= ((pA.Y + pB.Y + pC.Y) / 3) * triangleArea;
                    zc0 -= ((pA.Z + pB.Z + pC.Z) / 3) * triangleArea;
                }
            }

            foreach (ICurve crv in curveSubParts)
            {
                if (crv is Arc)
                {
                    double alpha = (crv as Arc).EndAngle - (crv as Arc).StartAngle;
                    double area  = (Math.Pow((crv as Arc).Radius, 2) / 2) * (alpha - Math.Sin(alpha));

                    Point p1 = crv.IStartPoint();
                    Point p2 = PointAtParameter(crv as Arc, 0.5);
                    Point p3 = crv.IEndPoint();

                    Point arcCentr = CircularSegmentCentroid(crv as Arc);

                    if (DotProduct(CrossProduct(p2 - p1, p3 - p1), firstNormal) > 0)
                    {
                        xc0 += arcCentr.X * area;
                        yc0 += arcCentr.Y * area;
                        zc0 += arcCentr.Z * area;
                    }
                    else
                    {
                        xc0 -= arcCentr.X * area;
                        yc0 -= arcCentr.Y * area;
                        zc0 -= arcCentr.Z * area;
                    }
                }
            }


            if (!dir)
            {
                xc0 = -xc0;
                yc0 = -yc0;
                zc0 = -zc0;
            }

            double curveArea = curve.Area();

            xc = xc0 / curveArea;
            yc = yc0 / curveArea;
            zc = zc0 / curveArea;

            return(new Point {
                X = xc, Y = yc, Z = zc
            });
        }
Exemple #3
0
        public static Point Centroid(this PolyCurve curve, double tolerance = Tolerance.Distance)
        {
            if (!curve.IsPlanar(tolerance))
            {
                Reflection.Compute.RecordError("Input curve is not planar. Cannot calculate centroid.");
                return(null);
            }
            else if (!curve.IsClosed(tolerance))
            {
                Reflection.Compute.RecordError("Input curve is not closed. Cannot calculate centroid.");
                return(null);
            }
            else if (curve.IsSelfIntersecting(tolerance))
            {
                Reflection.Compute.RecordError("Input curve is self-intersecting. Cannot calculate centroid.");
                return(null);
            }

            List <ICurve> curveSubParts = curve.SubParts();

            if (curveSubParts.Count == 1 && curveSubParts[0] is Circle)
            {
                return((curveSubParts[0] as Circle).Centre);
            }

            List <Point> pts = new List <Point> {
                curveSubParts[0].IStartPoint()
            };

            foreach (ICurve crv in curveSubParts)
            {
                if (crv is Line)
                {
                    pts.Add((crv as Line).End);
                }
                else if (crv is Arc)
                {
                    pts.Add(crv.IEndPoint());
                }
                else
                {
                    Reflection.Compute.RecordError("PolyCurve consisting of type: " + crv.GetType().Name + " is not implemented for Centroid.");
                    return(null);
                }
            }

            double xc, yc, zc;
            double xc0 = 0, yc0 = 0, zc0 = 0;

            Vector normal = Normal(curve, tolerance);

            //Check if a normal could be found.
            if (normal == null)
            {
                return(null);
            }

            Point pA = pts[0];

            for (int i = 1; i < pts.Count - 2; i++)
            {
                Point pB = pts[i];
                Point pC = pts[i + 1];

                double triangleArea = Area(pB - pA, pC - pA);

                if (DotProduct(CrossProduct(pB - pA, pC - pA), normal) > 0)
                {
                    xc0 += ((pA.X + pB.X + pC.X) / 3) * triangleArea;
                    yc0 += ((pA.Y + pB.Y + pC.Y) / 3) * triangleArea;
                    zc0 += ((pA.Z + pB.Z + pC.Z) / 3) * triangleArea;
                }
                else
                {
                    xc0 -= ((pA.X + pB.X + pC.X) / 3) * triangleArea;
                    yc0 -= ((pA.Y + pB.Y + pC.Y) / 3) * triangleArea;
                    zc0 -= ((pA.Z + pB.Z + pC.Z) / 3) * triangleArea;
                }
            }

            foreach (ICurve crv in curveSubParts)
            {
                if (crv is Arc)
                {
                    double alpha = (crv as Arc).EndAngle - (crv as Arc).StartAngle;
                    double area  = (Math.Pow((crv as Arc).Radius, 2) / 2) * (alpha - Math.Sin(alpha));

                    Point p1 = crv.IStartPoint();
                    Point p2 = PointAtParameter(crv as Arc, 0.5);
                    Point p3 = crv.IEndPoint();

                    Point arcCentr = CircularSegmentCentroid(crv as Arc);

                    if (DotProduct(CrossProduct(p2 - p1, p3 - p1), normal) > 0)
                    {
                        xc0 += arcCentr.X * area;
                        yc0 += arcCentr.Y * area;
                        zc0 += arcCentr.Z * area;
                    }
                    else
                    {
                        xc0 -= arcCentr.X * area;
                        yc0 -= arcCentr.Y * area;
                        zc0 -= arcCentr.Z * area;
                    }
                }
            }

            double curveArea = curve.Area();

            xc = xc0 / curveArea;
            yc = yc0 / curveArea;
            zc = zc0 / curveArea;

            return(new Point {
                X = xc, Y = yc, Z = zc
            });
        }