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); } } }
/***************************************************/ 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 }); }
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 }); }