Skip to content

Commit 3ba16f9

Browse files
committed
refactor direction computation to better handle sub-ordinals
1 parent a3da4ca commit 3ba16f9

File tree

3 files changed

+75
-85
lines changed

3 files changed

+75
-85
lines changed

src/ewmh_m2m/geometry.py

+23-25
Original file line numberDiff line numberDiff line change
@@ -35,34 +35,32 @@ def build_absolute(self, container):
3535
y=int(container.y + self.y * container.h)
3636
)
3737

38-
def horizontally_overlap(self, other) -> bool:
39-
return self.y < other.y + other.h and self.y + self.h > other.y
40-
41-
def vertically_overlap(self, other) -> bool:
42-
return self.x < other.x + other.w and self.x + self.w > other.x
43-
44-
def overlap(self, other) -> bool:
45-
return self.horizontally_overlap(other) and self.vertically_overlap(other)
38+
@property
39+
def center(self) -> "Geometry":
40+
return Geometry(x=self.x + self.w / 2, y=self.y + self.h / 2)
4641

4742
def directions_to(self, other: "Geometry") -> typing.Collection[Ordinal]:
48-
result = set(Ordinal)
49-
if self.horizontally_overlap(other):
50-
result &= {o for o in Ordinal if abs(o.sin) < 0.5}
51-
elif self.vertically_overlap(other):
52-
result &= {o for o in Ordinal if abs(o.cos) < 0.5}
53-
else:
54-
result -= {o for o in Ordinal if o.value % 90 == 0}
55-
56-
if other.x > self.x:
57-
result &= {o for o in Ordinal if o.cos >= 0 }
58-
if other.y < self.y:
59-
result &= {o for o in Ordinal if o.sin >= 0 }
60-
if other.x < self.x:
61-
result &= {o for o in Ordinal if o.cos <= 0 }
62-
if other.y > self.y:
63-
result &= {o for o in Ordinal if o.sin <= 0 }
43+
vector = Geometry(
44+
other.center.x - self.center.x, other.center.y - self.center.y
45+
)
46+
vector_norm = math.sqrt(vector.x**2 + vector.y**2)
47+
vector_cos = vector.x / vector_norm
48+
vector_sin = -vector.y / vector_norm
6449

65-
return result
50+
res = list(
51+
sorted(
52+
[
53+
(
54+
(o.cos - vector_cos) ** 2 + (o.sin - vector_sin) ** 2,
55+
o,
56+
)
57+
for o in list(Ordinal)
58+
],
59+
key=lambda t: t[0],
60+
)
61+
)
62+
print(res)
63+
return [t[1] for t in res if t[0] <= 0.152]
6664

6765
def __eq__(self, other):
6866
return list(self) == list(other)

tests/test_geometry.py

+29-50
Original file line numberDiff line numberDiff line change
@@ -4,51 +4,6 @@
44

55
class TestGeometry:
66

7-
def test_horizontally_not_overlap(self):
8-
g1 = Geometry(0, 0, 1, 1)
9-
g2 = Geometry(10, 10, 1, 1)
10-
11-
assert not g1.horizontally_overlap(g2)
12-
assert not g2.horizontally_overlap(g1)
13-
14-
def test_horizontally_overlap(self):
15-
g1 = Geometry(0, 0, 10, 10)
16-
g2 = Geometry(100, 0, 10, 10)
17-
18-
assert g1.horizontally_overlap(g2)
19-
assert g2.horizontally_overlap(g1)
20-
21-
def test_vertically_not_overlap(self):
22-
g1 = Geometry(0, 0, 10, 10)
23-
g2 = Geometry(100, 100, 10, 10)
24-
25-
assert not g1.vertically_overlap(g2)
26-
assert not g2.vertically_overlap(g1)
27-
28-
def test_vertically_overlap(self):
29-
g1 = Geometry(0, 0, 10, 10)
30-
g2 = Geometry(0, 100, 10, 10)
31-
32-
assert g1.vertically_overlap(g2)
33-
assert g2.vertically_overlap(g1)
34-
35-
def test_not_overlap(self):
36-
g1 = Geometry(0, 0, 10, 10)
37-
g2 = Geometry(100, 0, 10, 10)
38-
g3 = Geometry(0, 100, 10, 10)
39-
40-
assert not g1.overlap(g2)
41-
assert not g2.overlap(g1)
42-
assert not g1.overlap(g3)
43-
assert not g3.overlap(g1)
44-
45-
def test_overlap(self):
46-
g1 = Geometry(0, 0, 10, 10)
47-
g2 = Geometry(1, 1, 8, 8)
48-
49-
assert g1.overlap(g2)
50-
assert g2.overlap(g1)
51-
527
def test_directions_aligned(self):
538
"""
549
0 1 2
@@ -59,7 +14,7 @@ def test_directions_aligned(self):
5914
g1 = Geometry(0, 0, 1, 1)
6015
g2 = Geometry(1, 0, 1, 1)
6116

62-
assert g1.directions_to(g2) == {Ordinal.EAST, Ordinal.EAST_NORTHEAST, Ordinal.EAST_SOUTHEAST}
17+
assert list(g1.directions_to(g2)) == [Ordinal.EAST]
6318

6419
def test_directions_not_aligned(self):
6520
"""
@@ -73,7 +28,7 @@ def test_directions_not_aligned(self):
7328
g1 = Geometry(0, 0, 1, 1)
7429
g2 = Geometry(1, 1, 1, 1)
7530

76-
assert g1.directions_to(g2) == {Ordinal.SOUTH_SOUTHEAST, Ordinal.SOUTHEAST, Ordinal.EAST_SOUTHEAST}
31+
assert list(g1.directions_to(g2)) == [Ordinal.SOUTHEAST]
7732

7833
def test_directions_overlap(self):
7934
"""
@@ -86,7 +41,31 @@ def test_directions_overlap(self):
8641
g1 = Geometry(0, 0, 2, 2)
8742
g2 = Geometry(2, 1, 2, 2)
8843

89-
assert g1.directions_to(g2) == {
90-
Ordinal.EAST,
44+
assert list(g1.directions_to(g2)) == [
9145
Ordinal.EAST_SOUTHEAST,
92-
}
46+
Ordinal.SOUTHEAST,
47+
]
48+
49+
def test_gleb_setup(self):
50+
"""
51+
0 1080 3000
52+
0 ┌─────────┐
53+
130 ┌─────┤ │
54+
│ │ g1 │
55+
│ │ │
56+
1080 │ g2 ├─────────┤
57+
│ │ │
58+
│ │ g3 │
59+
2050 └─────┤ │
60+
2160 └─────────┘
61+
"""
62+
g1 = Geometry(1080, 0, 1920, 1080)
63+
g2 = Geometry(0, 130, 1080, 1920)
64+
g3 = Geometry(1080, 1080, 1920, 1080)
65+
66+
assert list(g1.directions_to(g2)) == [Ordinal.WEST_SOUTHWEST, Ordinal.WEST]
67+
assert list(g1.directions_to(g3)) == [Ordinal.SOUTH]
68+
assert list(g2.directions_to(g1)) == [Ordinal.EAST_NORTHEAST, Ordinal.EAST]
69+
assert list(g2.directions_to(g3)) == [Ordinal.EAST_SOUTHEAST, Ordinal.EAST]
70+
assert list(g3.directions_to(g1)) == [Ordinal.NORTH]
71+
assert list(g3.directions_to(g2)) == [Ordinal.WEST_NORTHWEST, Ordinal.WEST]

tests/test_screen.py

+23-10
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,21 @@ def test_siblings_vertical(self):
5151
assert siblings[Ordinal.NORTH] == [Geometry(0, 10, 10, 10), Geometry(0, 0, 10, 10)]
5252

5353
def test_siblings(self):
54+
"""
55+
0 1 2 3 4 5
56+
57+
0 ┌───┬───┬───┬───┬───┐
58+
│ NW│NNW│ N │NNE│ NE│
59+
1 ├───┼───┼───┼───┼───┤
60+
│WNW│ NW│ N │ NE│ENE│
61+
2 ├───┼───┼───┼───┼───┤
62+
│ W │ W │ c │ E │ E │
63+
3 ├───┼───┼───┼───┼───┤
64+
│WSW│ SW│ S │ SE│ESE│
65+
4 ├───┼───┼───┼───┼───┤
66+
│ SW│SSW│ S │SSE│ SE│
67+
5 └───┴───┴───┴───┴───┘
68+
"""
5469
screens = sorted(
5570
[Geometry(x, y, 1, 1) for x in range(5) for y in range(5)],
5671
key=lambda g: random.random())
@@ -68,16 +83,14 @@ def test_siblings(self):
6883
assert siblings[Ordinal.SOUTHWEST] == [Geometry(1, 3, 1, 1), Geometry(1, 4, 1, 1), Geometry(0, 3, 1, 1), Geometry(0, 4, 1, 1)]
6984
assert siblings[Ordinal.SOUTHEAST] == [Geometry(3, 3, 1, 1), Geometry(3, 4, 1, 1), Geometry(4, 3, 1, 1), Geometry(4, 4, 1, 1)]
7085

71-
assert set(siblings[Ordinal.EAST_NORTHEAST]) == set(siblings[Ordinal.EAST] + siblings[Ordinal.NORTHEAST])
72-
assert set(siblings[Ordinal.NORTH_NORTHEAST]) == set(siblings[Ordinal.NORTH] + siblings[Ordinal.NORTHEAST])
73-
assert set(siblings[Ordinal.NORTH_NORTHWEST]) == set(siblings[Ordinal.NORTH] + siblings[Ordinal.NORTHWEST])
74-
assert set(siblings[Ordinal.WEST_NORTHWEST]) == set(siblings[Ordinal.WEST] + siblings[Ordinal.NORTHWEST])
75-
assert set(siblings[Ordinal.WEST_SOUTHWEST]) == set(siblings[Ordinal.WEST] + siblings[Ordinal.SOUTHWEST])
76-
assert set(siblings[Ordinal.SOUTH_SOUTHWEST]) == set(siblings[Ordinal.SOUTH] + siblings[Ordinal.SOUTHWEST])
77-
assert set(siblings[Ordinal.SOUTH_SOUTHEAST]) == set(siblings[Ordinal.SOUTH] + siblings[Ordinal.SOUTHEAST])
78-
assert set(siblings[Ordinal.EAST_SOUTHEAST]) == set(siblings[Ordinal.EAST] + siblings[Ordinal.SOUTHEAST])
79-
80-
86+
assert siblings[Ordinal.EAST_NORTHEAST] == [Geometry(4, 1, 1, 1)]
87+
assert siblings[Ordinal.NORTH_NORTHEAST] == [Geometry(3, 0, 1, 1)]
88+
assert siblings[Ordinal.NORTH_NORTHWEST] == [Geometry(1, 0, 1, 1)]
89+
assert siblings[Ordinal.WEST_NORTHWEST] == [Geometry(0, 1, 1, 1)]
90+
assert siblings[Ordinal.WEST_SOUTHWEST] == [Geometry(0, 3, 1, 1)]
91+
assert siblings[Ordinal.SOUTH_SOUTHWEST] == [Geometry(1, 4, 1, 1)]
92+
assert siblings[Ordinal.SOUTH_SOUTHEAST] == [Geometry(3, 4, 1, 1)]
93+
assert siblings[Ordinal.EAST_SOUTHEAST] == [Geometry(4, 3, 1, 1)]
8194

8295
def test_siblings_gh_issue_14(self):
8396
"""

0 commit comments

Comments
 (0)