Skip to content

Commit 71dc6c9

Browse files
authored
Merge pull request #785 from compas-dev/length_eq
fix custom magic methods and add tests
2 parents 0c234a2 + 364b32b commit 71dc6c9

File tree

7 files changed

+148
-33
lines changed

7 files changed

+148
-33
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919
* Fixed bug where mimic joints were considered configurable.
2020
* Fixed bug where `!=` gave incorrect results in Rhino for some compas objects.
2121
* Fixed bug where `compas_rhino.BaseArtist.redraw` did not trigger a redraw.
22+
* Fixed minor bugs in `compas.geometry.Polyline` and `compas.geometry.Polygon`.
23+
* Fixed very minor bugs in `compas.geometry.Frame` and `compas.geometry.Quaternion`.
2224

2325
### Removed
2426

src/compas/geometry/primitives/frame.py

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
from __future__ import print_function
22

3-
import math
4-
5-
from compas.geometry import cross_vectors
6-
from compas.geometry import subtract_vectors
7-
from compas.geometry import matrix_from_basis_vectors
8-
from compas.geometry import basis_vectors_from_matrix
9-
from compas.geometry import quaternion_from_matrix
10-
from compas.geometry import matrix_from_quaternion
3+
from compas.geometry import allclose
4+
from compas.geometry import argmax
115
from compas.geometry import axis_angle_vector_from_matrix
12-
from compas.geometry import matrix_from_axis_angle_vector
6+
from compas.geometry import basis_vectors_from_matrix
7+
from compas.geometry import cross_vectors
8+
from compas.geometry import decompose_matrix
139
from compas.geometry import euler_angles_from_matrix
10+
from compas.geometry import matrix_from_axis_angle_vector
11+
from compas.geometry import matrix_from_basis_vectors
1412
from compas.geometry import matrix_from_euler_angles
15-
from compas.geometry import decompose_matrix
13+
from compas.geometry import matrix_from_quaternion
14+
from compas.geometry import quaternion_from_matrix
15+
from compas.geometry import subtract_vectors
1616
from compas.geometry import Transformation
17-
from compas.geometry import argmax
1817

19-
from compas.geometry.primitives import Primitive
2018
from compas.geometry.primitives import Point
21-
from compas.geometry.primitives import Vector
19+
from compas.geometry.primitives import Primitive
2220
from compas.geometry.primitives import Quaternion
21+
from compas.geometry.primitives import Vector
2322

2423
__all__ = ['Frame']
2524

@@ -180,11 +179,9 @@ def __iter__(self):
180179
return iter([self.point, self.xaxis, self.yaxis])
181180

182181
def __eq__(self, other, tol=1e-05):
183-
for v1, v2 in zip(self, other):
184-
for a, b in zip(v1, v2):
185-
if math.fabs(a - b) > tol:
186-
return False
187-
return True
182+
if not hasattr(other, '__iter__') or not hasattr(other, '__len__') or len(self) != len(other):
183+
return False
184+
return allclose(self, other)
188185

189186
# ==========================================================================
190187
# constructors
@@ -742,5 +739,4 @@ def transform(self, T):
742739
if __name__ == '__main__':
743740

744741
import doctest
745-
from compas.geometry import allclose # noqa: F401
746742
doctest.testmod(globs=globals())

src/compas/geometry/primitives/polygon.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@
44

55
import math
66

7+
from compas.geometry import allclose
8+
from compas.geometry import area_polygon
79
from compas.geometry import cross_vectors
810
from compas.geometry import centroid_polygon
9-
from compas.geometry import area_polygon
1011
from compas.geometry import is_coplanar
1112
from compas.geometry import is_polygon_convex
1213
from compas.geometry import transform_points
1314

14-
from compas.geometry.primitives import Primitive
15+
from compas.geometry.primitives import Line
1516
from compas.geometry.primitives import Point
17+
from compas.geometry.primitives import Primitive
1618
from compas.geometry.primitives import Vector
17-
from compas.geometry.primitives import Line
1819

1920
from compas.utilities import pairwise
2021

@@ -147,7 +148,7 @@ def area(self):
147148
# ==========================================================================
148149

149150
def __repr__(self):
150-
return "Polygon({})".format(", ".join(["{}".format(point) for point in self.points]))
151+
return "Polygon([{}])".format(", ".join(["{}".format(point) for point in self.points]))
151152

152153
def __len__(self):
153154
return len(self.points)
@@ -156,13 +157,16 @@ def __getitem__(self, key):
156157
return self.points[key]
157158

158159
def __setitem__(self, key, value):
159-
self.points[key] = value
160+
self.points[key] = Point(*value)
161+
self._lines = None
160162

161163
def __iter__(self):
162164
return iter(self.points)
163165

164166
def __eq__(self, other):
165-
return all(a == b for a, b in zip(self, other))
167+
if not hasattr(other, '__iter__') or not hasattr(other, '__len__') or len(self) != len(other):
168+
return False
169+
return allclose(self, other)
166170

167171
# ==========================================================================
168172
# constructors

src/compas/geometry/primitives/polyline.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
from __future__ import absolute_import
33
from __future__ import division
44

5+
from compas.geometry import allclose
56
from compas.geometry import transform_points
67

8+
from compas.geometry.predicates import is_point_on_line
9+
from compas.geometry.primitives import Line
710
from compas.geometry.primitives import Primitive
811
from compas.geometry.primitives import Point
9-
from compas.geometry.primitives import Line
10-
from compas.geometry.predicates import is_point_on_line
1112

1213
from compas.utilities import pairwise
1314

@@ -109,7 +110,7 @@ def length(self):
109110
# ==========================================================================
110111

111112
def __repr__(self):
112-
return "Polyline({})".format(", ".join(["{}".format(point) for point in self.points]))
113+
return "Polyline([{}])".format(", ".join(["{}".format(point) for point in self.points]))
113114

114115
def __len__(self):
115116
return len(self.points)
@@ -118,13 +119,16 @@ def __getitem__(self, key):
118119
return self.points[key]
119120

120121
def __setitem__(self, key, value):
121-
self.points[key] = value
122+
self.points[key] = Point(*value)
123+
self._lines = None
122124

123125
def __iter__(self):
124126
return iter(self.points)
125127

126128
def __eq__(self, other):
127-
return all(a == b for a, b in zip(self, other))
129+
if not hasattr(other, '__iter__') or not hasattr(other, '__len__') or len(self) != len(other):
130+
return False
131+
return allclose(self, other)
128132

129133
# ==========================================================================
130134
# constructors

src/compas/geometry/primitives/quaternion.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ def __setitem__(self, key, value):
217217
raise KeyError
218218

219219
def __eq__(self, other, tol=1e-05):
220+
if not hasattr(other, '__iter__') or not hasattr(other, '__len__') or len(self) != len(other):
221+
return False
220222
for v1, v2 in zip(self, other):
221223
if math.fabs(v1 - v2) > tol:
222224
return False
@@ -225,6 +227,9 @@ def __eq__(self, other, tol=1e-05):
225227
def __iter__(self):
226228
return iter(self.wxyz)
227229

230+
def __len__(self):
231+
return 4
232+
228233
def __repr__(self):
229234
return 'Quaternion({:.{prec}f}, {:.{prec}f}, {:.{prec}f}, {:.{prec}f})'.format(self.w, self.x, self.y, self.z, prec=3)
230235

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import pytest
2+
3+
from compas.geometry import Point
4+
from compas.geometry import Polygon
5+
from compas.utilities import pairwise
6+
7+
8+
def test_polygon():
9+
points = [[0, 0, x] for x in range(5)]
10+
polygon = Polygon(points)
11+
assert polygon.points == points
12+
assert polygon.lines == [(a, b) for a, b in pairwise(points + points[:1])]
13+
14+
15+
def test_equality():
16+
points1 = [[0, 0, x] for x in range(5)]
17+
polygon1 = Polygon(points1)
18+
points2 = [[0, 0, x] for x in range(6)]
19+
polygon2 = Polygon(points2)
20+
points3 = [[0, 0, x] for x in range(5)] + [[0, 0, 0]]
21+
polygon3 = Polygon(points3)
22+
assert polygon1 == polygon1
23+
assert polygon1 == points1
24+
assert points1 == polygon1
25+
assert polygon1 != polygon2
26+
assert polygon2 != polygon1
27+
assert polygon1 != points2
28+
assert points2 != polygon1
29+
assert polygon1 != 1
30+
assert polygon1 == polygon3
31+
32+
33+
def test___repr__():
34+
points = [[0, 0, x] for x in range(5)]
35+
polygon = Polygon(points)
36+
assert polygon == eval(repr(polygon))
37+
38+
39+
def test___getitem__():
40+
points = [[0, 0, x] for x in range(5)]
41+
polygon = Polygon(points)
42+
for x in range(5):
43+
assert polygon[x] == [0, 0, x]
44+
with pytest.raises(IndexError):
45+
polygon[6] = [0, 0, 6]
46+
47+
48+
def test___setitem__():
49+
points = [[0, 0, x] for x in range(5)]
50+
polygon = Polygon(points)
51+
point = [1, 1, 4]
52+
polygon[4] = point
53+
assert polygon[4] == point
54+
assert isinstance(polygon[4], Point)
55+
assert polygon.lines[-2].end == point

tests/compas/geometry/test_polyline.py

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,56 @@
1-
import compas
2-
import pytest
3-
from compas.geometry import Polyline, Point
41
import math
2+
import pytest
3+
4+
from compas.geometry import Point
5+
from compas.geometry import Polyline
6+
from compas.utilities import pairwise
7+
8+
9+
def test_polyline():
10+
points = [[0, 0, x] for x in range(5)]
11+
polyline = Polyline(points)
12+
assert polyline.points == points
13+
assert polyline.lines == [(a, b) for a, b in pairwise(points)]
14+
15+
16+
def test_equality():
17+
points1 = [[0, 0, x] for x in range(5)]
18+
polyline1 = Polyline(points1)
19+
points2 = [[0, 0, x] for x in range(6)]
20+
polyline2 = Polyline(points2)
21+
assert polyline1 == polyline1
22+
assert polyline1 == points1
23+
assert points1 == polyline1
24+
assert polyline1 != polyline2
25+
assert polyline2 != polyline1
26+
assert polyline1 != points2
27+
assert points2 != polyline1
28+
assert polyline1 != 1
29+
30+
31+
def test___repr__():
32+
points = [[0, 0, x] for x in range(5)]
33+
polyline = Polyline(points)
34+
assert polyline == eval(repr(polyline))
35+
36+
37+
def test___getitem__():
38+
points = [[0, 0, x] for x in range(5)]
39+
polyline = Polyline(points)
40+
for x in range(5):
41+
assert polyline[x] == [0, 0, x]
42+
with pytest.raises(IndexError):
43+
polyline[6] = [0, 0, 6]
44+
45+
46+
def test___setitem__():
47+
points = [[0, 0, x] for x in range(5)]
48+
polyline = Polyline(points)
49+
point = [1, 1, 4]
50+
polyline[4] = point
51+
assert polyline[4] == point
52+
assert isinstance(polyline[4], Point)
53+
assert polyline.lines[-1].end == point
554

655

756
@pytest.mark.parametrize('coords,expected', [

0 commit comments

Comments
 (0)