diff --git a/ladybug_geometry/geometry3d/line.py b/ladybug_geometry/geometry3d/line.py index 46860074..63c6f9b9 100644 --- a/ladybug_geometry/geometry3d/line.py +++ b/ladybug_geometry/geometry3d/line.py @@ -3,6 +3,7 @@ from __future__ import division from .pointvector import Point3D, Vector3D +from ..intersection3d import closest_point3d_on_line3d_infinite from ._1d import Base1DIn3D @@ -123,6 +124,32 @@ def is_vertical(self, tolerance): """ return abs(self.v.x) <= tolerance and abs(self.v.y) <= tolerance + def is_colinear(self, line_ray, tolerance, angle_tolerance=None): + """Test whether this object is colinear to another LineSegment3D or Ray3D. + + Args: + line_ray: Another LineSegment3D or Ray3D for which co-linearity + with this object will be tested. + tolerance: The maximum distance between the line_ray and the infinite + extension of this object for them to be considered colinear. + angle_tolerance: The max angle in radians that the direction between + this object and another can vary for them to be considered + parallel. If None, the angle tolerance will not be used to + evaluate co-linearity and the lines will only be considered + colinear if the endpoints of one line are within the tolerance + distance of the other line. (Default: None). + """ + if angle_tolerance is not None and \ + not self.is_parallel(line_ray, angle_tolerance): + return False + _close_pt = closest_point3d_on_line3d_infinite(self.p1, line_ray) + if self.p1.distance_to_point(_close_pt) >= tolerance: + return False + _close_pt = closest_point3d_on_line3d_infinite(self.p2, line_ray) + if self.p2.distance_to_point(_close_pt) >= tolerance: + return False + return True + def flip(self): """Get a copy of this line segment that is flipped.""" return LineSegment3D(self.p2, self.v.reverse()) diff --git a/ladybug_geometry/geometry3d/polyface.py b/ladybug_geometry/geometry3d/polyface.py index 4f01a9cf..ab24cb70 100644 --- a/ladybug_geometry/geometry3d/polyface.py +++ b/ladybug_geometry/geometry3d/polyface.py @@ -421,7 +421,7 @@ def is_solid(self): """ return self._is_solid - def merge_overlapping_edges(self, tolerance, angle_tolerance): + def merge_overlapping_edges(self, tolerance, angle_tolerance=None): """Get this object with overlapping naked edges merged into single internal edges This can be used to determine if a polyface is truly solid since this check @@ -447,8 +447,11 @@ def merge_overlapping_edges(self, tolerance, angle_tolerance): Args: tolerance: The minimum distance between a vertex and the boundary segments at which point the vertex is considered colinear. - angle_tolerance: The max angle in radians that vertices are allowed to - differ from one another in order to consider them colinear. + angle_tolerance: An optional maximum angle in radians to dictate + whether polyface edges are colinear with one another. If None, + the solidity of the polyface will be determined using only the + absolute distance of vertices to polyface edges in relation to + the tolerance. (Default: None). """ # get naked edges naked_edges = list(self.naked_edges)