Skip to content

Commit

Permalink
fix(line): Fix bug in LineSegment.subdivide_evenly method
Browse files Browse the repository at this point in the history
This commit fixes a Python tolerance issue that can sometimes arise in the LineSegment.subdivide_evenly method. I was only able to find this one after testing it on several thousand line segments in Rhino. Glad that this bug is squashed!
  • Loading branch information
chriswmackey committed Nov 1, 2019
1 parent b15efc5 commit 3546f4f
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 5 deletions.
5 changes: 3 additions & 2 deletions ladybug_geometry/geometry2d/line.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,14 @@ def subdivide_evenly(self, number):
Args:
number: The number of segments into which the line will be divided.
"""
interval = 1 / number
interval = 1 / number # can create tolerance issue where interval * number < 1
parameter = interval
sub_pts = [self.p]
while parameter < 1:
sub_pts.append(self.point_at(parameter))
parameter += interval
sub_pts.append(self.p2)
if len(sub_pts) != number + 1: # avoid tolerance issue from interval division
sub_pts.append(self.p2)
return sub_pts

def point_at(self, parameter):
Expand Down
8 changes: 5 additions & 3 deletions ladybug_geometry/geometry3d/line.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,17 @@ def subdivide_evenly(self, number):
"""Get Point3D values along the line that divide it into evenly-spaced segments.
Args:
number: The number of segments into which the line will be divided.
number: Integer for the number of segments into which the line will
be divided.
"""
interval = 1 / number
interval = 1 / number # can create tolerance issue where interval * number < 1
parameter = interval
sub_pts = [self.p]
while parameter < 1:
sub_pts.append(self.point_at(parameter))
parameter += interval
sub_pts.append(self.p2)
if len(sub_pts) != number + 1: # avoid tolerance issue from interval division
sub_pts.append(self.p2)
return sub_pts

def point_at(self, parameter):
Expand Down
13 changes: 13 additions & 0 deletions tests/line3d_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,19 @@ def test_subdivide():
assert divisions[4] == Point3D(2, 4, 2)


def test_subdivide_tolerance_issue():
"""Test the LineSegment3D subdivide method handles Python tolerance.
This case was taken from an originally failing situation in Rhino.
"""
origin = Point3D(-68.773857131759087, 20.836167334772536, 18.897600000000001)
dir = Vector3D(-0.026879795220556984, -0.99963867302585929, 0.0)
bottom_seg = LineSegment3D.from_sdl(origin, dir, 21.5037894118)

assert len(bottom_seg.subdivide_evenly(5)) == 6
assert len(bottom_seg.subdivide_evenly(7)) == 8


def test_closest_point():
"""Test the LineSegment3D closest_point method."""
pt = Point3D(2, 2, 2)
Expand Down

0 comments on commit 3546f4f

Please sign in to comment.