Skip to content

Commit

Permalink
fix(face): Improve calculation of normal from Face3D
Browse files Browse the repository at this point in the history
It seems I needed to bump this relative tolerance up to deal with some cases from Rhino. The other cases still pass so I think we are ok.
  • Loading branch information
chriswmackey committed Jul 29, 2021
1 parent 6040736 commit 1f6c03a
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 3 deletions.
2 changes: 1 addition & 1 deletion ladybug_geometry/geometry3d/face.py
Original file line number Diff line number Diff line change
Expand Up @@ -1924,7 +1924,7 @@ def _plane_from_vertices(verts):
cprods.append(cprodx)
ds.append(dx)
# sum together the cross products of any vertices that are not colinear
min_d = (sum(ds) / len(ds)) * 1e-3 # rel tolerance for colinear vertices
min_d = (sum(ds) / len(ds)) * 0.05 # rel tolerance for colinear vertices
normal = [0, 0, 0]
for cprodx, dx in zip(cprods, ds):
if dx > min_d:
Expand Down
16 changes: 14 additions & 2 deletions tests/face3d_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ def test_normal_with_slightly_nonplanar():
face_geo = Face3D.from_dict(geo_dict)

assert 0.99 < face_geo.normal.z < 1.01
assert face_geo.check_planar(0.000001, False) is False
assert not face_geo.check_planar(0.000001, False)
with pytest.raises(Exception):
face_geo.check_planar(0.000001)

Expand All @@ -714,6 +714,18 @@ def test_normal_with_colinear_vertices():
assert -0.01 < face_geos[1].normal.z < 0.01


def test_normal_with_jagged_vertices():
"""Test that shapes with colinear vertices have a relatively close normal."""
geo_file = './tests/json/face_jagged.json'
with open(geo_file, 'r') as fp:
geo_dict = json.load(fp)
face_geo = Face3D.from_dict(geo_dict)

assert 0.99 < face_geo.normal.z < 1.01
assert not face_geo.check_planar(0.000001, False)
face_geo.remove_colinear_vertices(0.01) # correct plan ensures removal of verts


def test_flip():
"""Test the flip method of Face3D."""
pts_1 = (Point3D(0, 0, 2), Point3D(2, 0, 2), Point3D(2, 2, 2), Point3D(0, 2, 2))
Expand Down Expand Up @@ -1103,7 +1115,7 @@ def test_contour_fins_by_distance_between():
assert len(fins) == 4

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

fins = face_2.contour_fins_by_distance_between(
Expand Down
100 changes: 100 additions & 0 deletions tests/json/face_jagged.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{
"type": "Face3D",
"boundary": [
[
-2.1694429082929334,
222.2891752214797,
61.0
],
[
-2.1694429083407409,
204.9141880746771,
61.0
],
[
25.962446729946357,
204.91418752003045,
61.0
],
[
25.962446551501184,
204.68183146374975,
61.0
],
[
105.58889704854292,
204.68183146374975,
61.0
],
[
105.58889704870727,
202.82654893892854,
61.0
],
[
145.04723038220482,
202.82654893841612,
61.0
],
[
145.0472303818751,
203.2200197818172,
61.0
],
[
253.03889387546633,
203.22001922761362,
61.0
],
[
253.03889215557112,
222.28903649101895,
61.0
],
[
170.61508412845217,
222.28908129634578,
61.0
],
[
170.61508412845214,
216.23382782259063,
61.0
],
[
169.73640447201186,
214.11250747903102,
61.0
],
[
167.61508412845225,
213.23382782259063,
61.0
],
[
157.36508328771052,
213.23382782259048,
61.0
],
[
69.831239017732798,
213.23382782259063,
60.999997819662397
],
[
67.709918674173124,
214.11250747903097,
60.999997883900605
],
[
66.831239017732756,
216.23382782259063,
60.999997910508938
],
[
66.83123901773277,
222.28913771292264,
61.0
]
]
}

0 comments on commit 1f6c03a

Please sign in to comment.