diff --git a/Geometry_Engine/Query/DominantEdgeDirection.cs b/Geometry_Engine/Query/DominantEdgeDirection.cs new file mode 100644 index 000000000..fdc96fd33 --- /dev/null +++ b/Geometry_Engine/Query/DominantEdgeDirection.cs @@ -0,0 +1,60 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2026, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Base.Attributes; +using BH.oM.Geometry; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; + +namespace BH.Engine.Geometry +{ + public static partial class Query + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + [Description("Returns the direction of the dominant edge of a polyline.")] + [Input("polyline", "Polyline whose edge directions are evaluated.")] + [Input("tolerance", "Minimum edge length.")] + [Input("angleTolerance", "Angular tolerance used when comparing edge directions for parallelism.")] + [Output("direction", "Direction vector of the dominant edge.")] + public static Vector DominantEdgeDirection(this Polyline polyline, double tolerance = Tolerance.Distance, double angleTolerance = Tolerance.Angle) + { + List edges = polyline.SubParts().Where(x => x != null && x.Length() > tolerance).ToList(); + Dictionary dirLen = new Dictionary(); + foreach (Line edge in edges) + { + Vector direction = edge.Direction(); + Vector existDir = dirLen.Keys.FirstOrDefault(x => x.IsParallel(direction, angleTolerance) != 0); + + if (existDir != null) + dirLen[existDir] += edge.Length(); + else + dirLen[direction] = edge.Length(); + } + + return dirLen.OrderByDescending(x => x.Value).First().Key; + } + } +} diff --git a/Geometry_Engine/Query/IsRectangular.cs b/Geometry_Engine/Query/IsRectangular.cs index 856108f56..70ea15ddb 100644 --- a/Geometry_Engine/Query/IsRectangular.cs +++ b/Geometry_Engine/Query/IsRectangular.cs @@ -20,15 +20,12 @@ * along with this code. If not, see . */ -using BH.oM.Geometry; using BH.oM.Base.Attributes; -using BH.Engine.Geometry; -using BH.Engine.Reflection; - +using BH.oM.Geometry; using System; using System.Collections.Generic; -using System.Linq; using System.ComponentModel; +using System.Linq; namespace BH.Engine.Geometry { @@ -40,7 +37,7 @@ public static partial class Query [Description("Determines whether a Polycurve is a rectangular.")] [Input("polycurve", "The Polycurve to check if it is rectangular.")] - [Output("bool", "True for Polycurves that are rectangular or false for Polycurves that are rectangular.")] + [Output("bool", "True for Polycurves that are rectangular or false for Polycurves that are not rectangular.")] public static bool IsRectangular(this PolyCurve polycurve) { if (polycurve == null) @@ -63,6 +60,30 @@ public static bool IsRectangular(this PolyCurve polycurve) return (angles.Any(x => Math.Abs(Math.PI / 2 - x) > Tolerance.Angle)) ? false : true; } + /***************************************************/ + + [Description("Checks whether a Polyline is a rectangular.")] + [Input("polyline", "The Polyline to check if it is rectangular.")] + [Input("tolerance", "Maximum allowed distance deviation for closure and diagonal equality checks.")] + [Output("isRectangular", "True for the Polylines that are rectangular or false for Polylines that are not rectangular.")] + public static bool IsRectangular(this Polyline polyline, double tolerance = Tolerance.Distance) + { + List pts = polyline?.ControlPoints; + if (pts == null || pts.Count != 5) + return false; + + if (polyline.IsPlanar(tolerance) != true) + return false; + + if (polyline.IsClosed(tolerance) != true) + return false; + + double diagonal1 = pts[2].Distance(pts[0]); + double diagonal2 = pts[3].Distance(pts[1]); + + return Math.Abs(diagonal1 - diagonal2) <= tolerance; + } + /***************************************************/ /**** Private Methods ****/ /***************************************************/