/***************************************************/ public static bool NormalAwayFromSpace(this BHG.Polyline pline, List <BHE.BuildingElement> elementsAsSpace) { List <BHG.Point> centrePtList = new List <BHG.Point>(); BHG.Point centrePt = pline.Centre(); centrePtList.Add(centrePt); if (!pline.IsClosed()) { return(false); //Prevent failures of the clockwise check } List <BHG.Point> pts = BH.Engine.Geometry.Query.DiscontinuityPoints(pline); if (pts.Count < 3) { return(false); //Protection in case there aren't enough points to make a plane } BHG.Plane plane = BH.Engine.Geometry.Create.Plane(pts[0], pts[1], pts[2]); //The polyline can be locally concave. Check if the polyline is clockwise. if (!BH.Engine.Geometry.Query.IsClockwise(pline, plane.Normal)) { plane.Normal = -plane.Normal; } if (!BH.Engine.Geometry.Query.IsContaining(pline, centrePtList, false)) { BHG.Point pointOnLine = BH.Engine.Geometry.Query.ClosestPoint(pline, centrePt); BHG.Vector vector = new BHG.Vector(); if (BH.Engine.Geometry.Query.Distance(pointOnLine, centrePt) > BH.oM.Geometry.Tolerance.MicroDistance) { vector = pointOnLine - centrePt; } else { BHG.Line line = BH.Engine.Geometry.Query.GetLineSegment(pline, pointOnLine); vector = ((line.Start - line.End).Normalise()).CrossProduct(plane.Normal); } centrePt = BH.Engine.Geometry.Modify.Translate(pointOnLine, BH.Engine.Geometry.Modify.Normalise(vector) * 0.001); } //Move centrepoint along the normal. if (BH.Engine.Environment.Query.IsContaining(elementsAsSpace, centrePt.Translate(plane.Normal * 0.01))) { return(false); } else { return(true); } }