Skip to content

Commit

Permalink
fix(tolerance): Require input of tolerance and do not use 0
Browse files Browse the repository at this point in the history
There really shouldn't be any case where a tolerance of 0 is used. So I am removing it as a default input across the library.

Resolves #89
  • Loading branch information
chriswmackey committed May 15, 2020
1 parent 1cce8d0 commit e79e383
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 92 deletions.
2 changes: 1 addition & 1 deletion ladybug_geometry/geometry2d/pointvector.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def magnitude_squared(self):
"""Get the magnitude squared of the vector."""
return self.x ** 2 + self.y ** 2

def is_zero(self, tolerance=0):
def is_zero(self, tolerance):
"""Boolean to note whether the vector is within a given zero tolerance.
Args:
Expand Down
67 changes: 34 additions & 33 deletions ladybug_geometry/geometry3d/face.py
Original file line number Diff line number Diff line change
Expand Up @@ -946,8 +946,7 @@ def mesh_grid(self, x_dim, y_dim=None, offset=None, flip=False,

return grid_mesh3d

def countour_by_number(self, contour_count, direction_vector=Vector2D(0, 1),
flip_side=False, tolerance=0):
def countour_by_number(self, contour_count, direction_vector, flip_side, tolerance):
"""Generate a list of LineSegment3D objects contouring the face.
Args:
Expand All @@ -957,13 +956,14 @@ def countour_by_number(self, contour_count, direction_vector=Vector2D(0, 1),
are generated. This 2D vector will be interpreted into a 3D vector
within the plane of this Face. (0, 1) will usually generate
horizontal contours in 3D space, (1, 0) will generate vertical
contours, and (1, 1) will generate diagonal contours. Default: (0, 1).
contours, and (1, 1) will generate diagonal contours. Recommended
value is Vactor2D(0, 1).
flip_side: Boolean to note whether the side the contours start from
should be flipped. Default is False to have contours on top or right.
should be flipped. Recommended value is False to have contours
on top or right.
Setting to True will start contours on the bottom or left.
tolerance: An optional value to remove any contours with a length less
than the tolerance. Default is 0, which will include all contours
no matter how small.
than the tolerance.
"""
# interpret the 2D direction_vector into one that exists in 3D space
ref_plane = Plane(self._plane.n, Point3D(0, 0, 0), self._plane.x)
Expand All @@ -988,8 +988,8 @@ def countour_by_number(self, contour_count, direction_vector=Vector2D(0, 1),
contours = [l_seg for l_seg in contours if l_seg.length >= tolerance]
return contours

def countour_by_distance_between(self, distance, direction_vector=Vector2D(0, 1),
flip_side=False, tolerance=0):
def countour_by_distance_between(self, distance, direction_vector, flip_side,
tolerance):
"""Generate a list of LineSegment3D objects contouring the face.
Args:
Expand All @@ -998,13 +998,14 @@ def countour_by_distance_between(self, distance, direction_vector=Vector2D(0, 1)
are generated. This 2D vector will be interpreted into a 3D vector
within the plane of this Face. (0, 1) will usually generate
horizontal contours in 3D space, (1, 0) will generate vertical
contours, and (1, 1) will generate diagonal contours. Default: (0, 1).
contours, and (1, 1) will generate diagonal contours. Recommended
value is Vector2D(0, 1).
flip_side: Boolean to note whether the side the contours start from
should be flipped. Default is False to have contours on top or right.
Setting to True will start contours on the bottom or left.
should be flipped. Recommended value is is False to have contours
start on top or right. Setting to True will start contours on
the bottom or left.
tolerance: An optional value to remove any contours with a length less
than the tolerance. Default is 0, which will include all contours
no matter how small.
than the tolerance.
"""
# interpret the 2D direction_vector into one that exists in 3D space
ref_plane = Plane(self._plane.n, Point3D(0, 0, 0), self._plane.x)
Expand Down Expand Up @@ -1035,58 +1036,58 @@ def countour_by_distance_between(self, distance, direction_vector=Vector2D(0, 1)
contours = [l_seg for l_seg in contours if l_seg.length >= tolerance]
return contours

def countour_fins_by_number(self, fin_count, depth, offset=0, angle=0,
contour_vector=Vector2D(0, 1), flip_side=False,
tolerance=0):
def countour_fins_by_number(self, fin_count, depth, offset, angle,
contour_vector, flip_side, tolerance):
"""Generate a list of Fac3D objects over this face (like louvers or fins).
Args:
fin_count: A positive integer for the number of fins to generate.
depth: A number for the depth to extrude the fins.
offset: A number for the distance to offset fins from this face.
Default is 0 for no offset.
Recommended value is 0 for no offset.
angle: A number for the for an angle to rotate the fins in radians.
Default is 0 for no rotation.
Recommended value is 0 for no rotation.
contour_vector: A Vector2D for the direction along which contours
are generated. This 2D vector will be interpreted into a 3D vector
within the plane of this Face. (0, 1) will usually generate
horizontal contours in 3D space, (1, 0) will generate vertical
contours, and (1, 1) will generate diagonal contours. Default: (0, 1).
contours, and (1, 1) will generate diagonal contours. Recommended
value is Vector2D(0, 1).
flip_side: Boolean to note whether the side the fins start from
should be flipped. Default is False to have contours on top or right.
Setting to True will start contours on the bottom or left.
should be flipped. Recommended value is False to have contours
start on top or right. Setting to True will start contours on
the bottom or left.
tolerance: An optional value to remove any contours with a length less
than the tolerance. Default is 0, which will include all contour fins
no matter how small.
than the tolerance.
"""
extru_vec = self._get_fin_extrusion_vector(depth, angle, contour_vector)
contours = self.countour_by_number(
fin_count, contour_vector, flip_side, tolerance)
return self._get_extrusion_fins(contours, extru_vec, offset)

def countour_fins_by_distance_between(self, distance, depth, offset=0, angle=0,
contour_vector=Vector2D(0, 1),
flip_side=False, tolerance=0):
def countour_fins_by_distance_between(self, distance, depth, offset, angle,
contour_vector, flip_side, tolerance):
"""Generate a list of Fac3D objects over this face (like louvers or fins).
Args:
distance: A number for the approximate distance between each contour.
depth: A number for the depth to extrude the fins.
offset: A number for the distance to offset fins from this face.
Default is 0 for no offset.
Recommended value is 0 for no offset.
angle: A number for the for an angle to rotate the fins in radians.
Default is 0 for no rotation.
Recommended value is 0 for no rotation.
contour_vector: A Vector2D for the direction along which contours
are generated. This 2D vector will be interpreted into a 3D vector
within the plane of this Face. (0, 1) will usually generate
horizontal contours in 3D space, (1, 0) will generate vertical
contours, and (1, 1) will generate diagonal contours. Default: (0, 1).
contours, and (1, 1) will generate diagonal contours. Recommended
value is Vector2D(0, 1).
flip_side: Boolean to note whether the side the fins start from
should be flipped. Default is False to have contours on top or right.
Setting to True will start contours on the bottom or left.
should be flipped. Recommended value is False to have contours
start on top or right. Setting to True will start contours on
the bottom or left.
tolerance: An optional value to remove any contours with a length less
than the tolerance. Default is 0, which will include all contour fins
no matter how small.
than the tolerance.
"""
extru_vec = self._get_fin_extrusion_vector(depth, angle, contour_vector)
contours = self.countour_by_distance_between(
Expand Down
2 changes: 1 addition & 1 deletion ladybug_geometry/geometry3d/pointvector.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def magnitude_squared(self):
"""Get the magnitude squared of the vector."""
return self.x ** 2 + self.y ** 2 + self.z ** 2

def is_zero(self, tolerance=0):
def is_zero(self, tolerance):
"""Boolean to note whether the vector is within a given zero tolerance.
Args:
Expand Down
10 changes: 5 additions & 5 deletions ladybug_geometry/geometry3d/polyface.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def from_dict(cls, data):
data['face_indices'], edge_information)

@classmethod
def from_faces(cls, faces, tolerance=0):
def from_faces(cls, faces, tolerance):
"""Initialize Polyface3D from a list of Face3D objects.
Note that the Polyface3D.faces property of the resulting polyface will
Expand All @@ -143,7 +143,7 @@ def from_faces(cls, faces, tolerance=0):
Args:
faces: A list of Face3D objects representing the boundary of this Polyface.
tolerance: The maximum difference between x, y, and z values at which
the vertex of two adjacent faces is considered the same. Default: 0.
the vertex of two adjacent faces is considered the same.
"""
# extract unique vertices from the faces
vertices = [] # collection of vertices as point objects
Expand Down Expand Up @@ -303,7 +303,7 @@ def faces(self):
holes = tuple(tuple(self.vertices[i] for i in f) for f in face[1:])
faces.append(Face3D(boundary=boundary, holes=holes))
if self._is_solid:
self._faces = Polyface3D.get_outward_faces(faces)
self._faces = Polyface3D.get_outward_faces(faces, 0)
else:
self._faces = tuple(faces)
return self._faces
Expand Down Expand Up @@ -711,8 +711,8 @@ def overlapping_bounding_boxes(polyface1, polyface2, tolerance):
return True # overlap exists

@staticmethod
def get_outward_faces(faces, tolerance=0):
"""Get faces that are all pointing outward from a list of faces together forming a solid.
def get_outward_faces(faces, tolerance):
"""Turn a list of faces forming a solid into one where they all point outward.
Note that, if the input faces do not form a closed solid, there may be some
output faces that are not pointing outward. However, if the gaps in the
Expand Down
48 changes: 25 additions & 23 deletions tests/face3d_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


def test_face3d_init():
"""Test the initalization of Face3D objects and basic properties."""
"""Test the initialization of Face3D objects and basic properties."""
pts = (Point3D(0, 0, 2), Point3D(0, 2, 2), Point3D(2, 2, 2), Point3D(2, 0, 2))
plane = Plane(Vector3D(0, 0, 1), Point3D(0, 0, 2))
face = Face3D(pts, plane)
Expand Down Expand Up @@ -82,7 +82,7 @@ def test_face3d_to_from_dict():


def test_face3d_init_from_vertices():
"""Test the initalization of Face3D objects without a plane."""
"""Test the initialization of Face3D objects without a plane."""
pts = (Point3D(0, 0, 2), Point3D(0, 2, 2), Point3D(2, 2, 2), Point3D(2, 0, 2))
face = Face3D(pts)

Expand Down Expand Up @@ -114,12 +114,12 @@ def test_face3d_init_from_vertices():


def test_face3d_init_from_vertices_colinear():
"""Test the initalization of Face3D objects with colinear vertices."""
"""Test the initialization of Face3D objects with colinear vertices."""
pts = (Point3D(0, 0, 2), Point3D(0, 1, 2), Point3D(0, 2, 2), Point3D(2, 2, 2),
Point3D(2, 0, 2))
face = Face3D(pts)

assert not face.normal.is_zero()
assert not face.normal.is_zero(0.000001)
assert face.plane.n == Vector3D(0, 0, -1)
assert face.plane.n == face.normal
assert face.plane.o == Point3D(0, 0, 2)
Expand Down Expand Up @@ -224,7 +224,7 @@ def test_face3d_init_from_regular_polygon():


def test_face3d_init_from_shape_with_hole():
"""Test the initalization of Face3D from_shape_with_holes with one hole."""
"""Test the initialization of Face3D from_shape_with_holes with one hole."""
bound_pts = [Point3D(0, 0), Point3D(4, 0), Point3D(4, 4), Point3D(0, 4)]
hole_pts = [Point3D(1, 1), Point3D(3, 1), Point3D(3, 3), Point3D(1, 3)]
face = Face3D(bound_pts, None, [hole_pts])
Expand Down Expand Up @@ -956,22 +956,22 @@ def test_countour_by_number():
face_1 = Face3D(pts_1, plane)
face_2 = Face3D(pts_2, plane)

contours = face_1.countour_by_number(4)
contours = face_1.countour_by_number(4, Vector2D(0, 1), False, 0.01)
assert len(contours) == 4
assert contours[0].p2.z == pytest.approx(2, rel=1e-3)
assert contours[-1].p2.z == pytest.approx(0.5, rel=1e-3)

contours = face_1.countour_by_number(4, Vector2D(1))
contours = face_1.countour_by_number(4, Vector2D(1), False, 0.01)
assert len(contours) == 4
assert contours[-1].p2.x == pytest.approx(1.5, rel=1e-3)

contours = face_1.countour_by_number(4, Vector2D(1), True)
contours = face_1.countour_by_number(4, Vector2D(1), True, 0.01)
assert len(contours) == 4
assert contours[-1].p2.x == pytest.approx(0.5, rel=1e-3)

contours = face_2.countour_by_number(4)
contours = face_2.countour_by_number(4, Vector2D(0, 1), False, 0.01)
assert len(contours) == 4
contours = face_2.countour_by_number(8, Vector2D(1))
contours = face_2.countour_by_number(8, Vector2D(1), False, 0.01)
assert len(contours) == 8


Expand All @@ -983,22 +983,22 @@ def test_countour_by_distance_between():
face_1 = Face3D(pts_1, plane)
face_2 = Face3D(pts_2, plane)

contours = face_1.countour_by_distance_between(0.5)
contours = face_1.countour_by_distance_between(0.5, Vector2D(0, 1), False, 0.01)
assert len(contours) == 4
assert contours[0].p2.z == pytest.approx(2, rel=1e-3)
assert contours[-1].p2.z == pytest.approx(0.5, rel=1e-3)

contours = face_1.countour_by_distance_between(0.5, Vector2D(1))
contours = face_1.countour_by_distance_between(0.5, Vector2D(1), False, 0.01)
assert len(contours) == 4
assert contours[-1].p2.x == pytest.approx(1.5, rel=1e-3)

contours = face_1.countour_by_distance_between(0.5, Vector2D(1), True)
contours = face_1.countour_by_distance_between(0.5, Vector2D(1), True, 0.01)
assert len(contours) == 4
assert contours[-1].p2.x == pytest.approx(0.5, rel=1e-3)

contours = face_2.countour_by_distance_between(0.5)
contours = face_2.countour_by_distance_between(0.5, Vector2D(0, 1), False, 0.01)
assert len(contours) == 4
contours = face_2.countour_by_distance_between(0.5, Vector2D(1))
contours = face_2.countour_by_distance_between(0.5, Vector2D(1), False, 0.01)
assert len(contours) == 8


Expand All @@ -1008,13 +1008,14 @@ def test_countour_fins_by_number():
plane = Plane(Vector3D(0, 1, 0))
face_1 = Face3D(pts_1, plane)

fins = face_1.countour_fins_by_number(4, 0.5, 0.5)
fins = face_1.countour_fins_by_number(4, 0.5, 0.5, 0, Vector2D(0, 1), False, 0.01)
assert len(fins) == 4

fins = face_1.countour_fins_by_number(4, 0.5, 0.5, contour_vector=Vector2D(1))
fins = face_1.countour_fins_by_number(4, 0.5, 0.5, 0, Vector2D(1), False, 0.01)
assert len(fins) == 4

fins = face_1.countour_fins_by_number(4, 0.5, 0.5, math.pi/4)
fins = face_1.countour_fins_by_number(
4, 0.5, 0.5, math.pi/4, Vector2D(0, 1), False, 0.01)
assert len(fins) == 4


Expand All @@ -1026,15 +1027,16 @@ def test_countour_fins_by_distance_between():
face_1 = Face3D(pts_1, plane)
face_2 = Face3D(pts_2, plane)

fins = face_1.countour_fins_by_distance_between(0.5, 0.5, 0.5)
fins = face_1.countour_fins_by_distance_between(
0.5, 0.5, 0.5, 0, Vector2D(0, 1), False, 0.01)
assert len(fins) == 4

fins = face_1.countour_fins_by_distance_between(0.25, 0.5, 0.5,
contour_vector=Vector2D(1))
fins = face_1.countour_fins_by_distance_between(
0.25, 0.5, 0.5,0, Vector2D(1), False, 0.01)
assert len(fins) == 8

fins = face_2.countour_fins_by_distance_between(0.5, 0.5, 0.5,
contour_vector=Vector2D(1))
fins = face_2.countour_fins_by_distance_between(
0.5, 0.5, 0.5, 0, Vector2D(1), False, 0.01)
assert len(fins) == 8


Expand Down
10 changes: 5 additions & 5 deletions tests/pointvector2d_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


def test_vector2_init():
"""Test the initalization of Vector2D objects and basic properties."""
"""Test the initialization of Vector2D objects and basic properties."""
vec = Vector2D(0, 2)
str(vec) # test the string representation of the vector

Expand All @@ -17,7 +17,7 @@ def test_vector2_init():
assert vec[1] == 2
assert vec.magnitude == 2
assert vec.magnitude_squared == 4
assert not vec.is_zero()
assert not vec.is_zero(0.0000001)

assert len(vec) == 2
pt_tuple = tuple(i for i in vec)
Expand All @@ -30,16 +30,16 @@ def test_vector2_init():


def test_zero_magnitude_vector():
"""Test properties with a zero magnitude vecotr."""
"""Test properties with a zero magnitude vector."""
vec = Vector2D(0, 0)

assert vec.is_zero()
assert vec.is_zero(0.0000001)
assert vec.magnitude == 0
assert vec.normalize() == vec


def test_vector2_to_from_dict():
"""Test the initalization of Vector2D objects and basic properties."""
"""Test the initialization of Vector2D objects and basic properties."""
vec = Vector2D(0, 2)
vec_dict = vec.to_dict()
new_vec = Vector2D.from_dict(vec_dict)
Expand Down

0 comments on commit e79e383

Please sign in to comment.