In case anyone finds this thread and has a similar issue, I was able to use an alternative method to get the aperture edges consistently. This method seems to work even with horizontal skylights, and other non-perpendicular apertures as well.
import math
from Rhino.RhinoDoc import ModelAbsoluteTolerance
import ghpythonlib.components as ghc
from ladybug_geometry.geometry3d import LineSegment3D, Plane
from ladybug_rhino.fromgeometry import from_face3d, from_linesegment3d, from_point3d, from_plane
from honeybee.aperture import Aperture
TOLERANCE = ModelAbsoluteTolerance
def calc_edge_angle_about_origin(_edge, _center_pt, _pl, _tol=0.0001):
# type: (LineSegment3D, Point3d, Plane, float) -> float
"""Calculate the angle of an edge's midpoint about the origin-point of its parent plane."""
# -- Get the edge's mid-point
rh_edge = from_linesegment3d(_edge)
edge_midpoint = ghc.CurveMiddle(rh_edge)
# -- Find the angle from the aperture's center-point, to the edges' midpoint
# -- Use the local y-axis so that if the aperture is moved or
# -- rotated or slanted (skylights) it will still work as expected
_, _, local_y_axis, _ = ghc.DeconstructPlane(_pl)
v = ghc.Vector2Pt(_center_pt, edge_midpoint, False).vector
angle = math.degrees(ghc.Angle(local_y_axis, v, _pl).angle)
angle = round(angle, 2)
# -- Ensure that floating-point errors (359.999999999998) won't mess up the order
if abs(angle - 360.0) <= _tol:
angle = 0.0
return angle
def get_ap_edges(_aperture, _tol=0.0001):
# type: (Aperture, float) -> List[LineSegment3D]
"""Sort the edges of the aperture based on their angle about the aperture's center point."""
aperture_face = from_face3d(_aperture.geometry)
aperture_local_plane = from_plane(_aperture.geometry.plane)
apeture_center_point = ghc.Area(aperture_face).centroid
# -- Get the edges in clockwise order (top, right, bottom, left)
edges_sorted = sorted(
_aperture.geometry.boundary_segments,
reverse=True,
key=lambda e: calc_edge_angle_about_origin(
e, apeture_center_point, aperture_local_plane, _tol
),
)
return edges_sorted
# -----
left_edges_, right_edges_ = [], []
for aperture in _aps:
top, right, bottom, left= get_ap_edges(aperture, _tol=TOLERANCE)
left_edges_.append(from_linesegment3d(left))
right_edges_.append(from_linesegment3d(right))
best
@edpmay
left_right_edges_test.gh (30.0 KB)