Skip to content

Commit

Permalink
refactor direction computation to better handle sub-ordinals
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexisBRENON committed Jul 23, 2024
1 parent a3da4ca commit 28f17ed
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 85 deletions.
48 changes: 23 additions & 25 deletions src/ewmh_m2m/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,32 @@ def build_absolute(self, container):
y=int(container.y + self.y * container.h)
)

def horizontally_overlap(self, other) -> bool:
return self.y < other.y + other.h and self.y + self.h > other.y

def vertically_overlap(self, other) -> bool:
return self.x < other.x + other.w and self.x + self.w > other.x

def overlap(self, other) -> bool:
return self.horizontally_overlap(other) and self.vertically_overlap(other)
@property
def center(self) -> "Geometry":
return Geometry(x=self.x + self.w / 2, y=self.y + self.h / 2)

def directions_to(self, other: "Geometry") -> typing.Collection[Ordinal]:
result = set(Ordinal)
if self.horizontally_overlap(other):
result &= {o for o in Ordinal if abs(o.sin) < 0.5}
elif self.vertically_overlap(other):
result &= {o for o in Ordinal if abs(o.cos) < 0.5}
else:
result -= {o for o in Ordinal if o.value % 90 == 0}

if other.x > self.x:
result &= {o for o in Ordinal if o.cos >= 0 }
if other.y < self.y:
result &= {o for o in Ordinal if o.sin >= 0 }
if other.x < self.x:
result &= {o for o in Ordinal if o.cos <= 0 }
if other.y > self.y:
result &= {o for o in Ordinal if o.sin <= 0 }
vector = Geometry(
other.center.x - self.center.x, other.center.y - self.center.y
)
vector_norm = math.sqrt(vector.x**2 + vector.y**2)
vector_cos = vector.x / vector_norm
vector_sin = -vector.y / vector_norm

return result
res = list(
sorted(
[
(
(o.cos - vector_cos) ** 2 + (o.sin - vector_sin) ** 2,
o,
)
for o in list(Ordinal)
],
key=lambda t: t[0],
)
)
print(res)
return [t[1] for t in res if t[0] <= 0.152]

def __eq__(self, other):
return list(self) == list(other)
Expand Down
80 changes: 30 additions & 50 deletions tests/test_geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,6 @@

class TestGeometry:

def test_horizontally_not_overlap(self):
g1 = Geometry(0, 0, 1, 1)
g2 = Geometry(10, 10, 1, 1)

assert not g1.horizontally_overlap(g2)
assert not g2.horizontally_overlap(g1)

def test_horizontally_overlap(self):
g1 = Geometry(0, 0, 10, 10)
g2 = Geometry(100, 0, 10, 10)

assert g1.horizontally_overlap(g2)
assert g2.horizontally_overlap(g1)

def test_vertically_not_overlap(self):
g1 = Geometry(0, 0, 10, 10)
g2 = Geometry(100, 100, 10, 10)

assert not g1.vertically_overlap(g2)
assert not g2.vertically_overlap(g1)

def test_vertically_overlap(self):
g1 = Geometry(0, 0, 10, 10)
g2 = Geometry(0, 100, 10, 10)

assert g1.vertically_overlap(g2)
assert g2.vertically_overlap(g1)

def test_not_overlap(self):
g1 = Geometry(0, 0, 10, 10)
g2 = Geometry(100, 0, 10, 10)
g3 = Geometry(0, 100, 10, 10)

assert not g1.overlap(g2)
assert not g2.overlap(g1)
assert not g1.overlap(g3)
assert not g3.overlap(g1)

def test_overlap(self):
g1 = Geometry(0, 0, 10, 10)
g2 = Geometry(1, 1, 8, 8)

assert g1.overlap(g2)
assert g2.overlap(g1)

def test_directions_aligned(self):
"""
0 1 2
Expand All @@ -59,7 +14,7 @@ def test_directions_aligned(self):
g1 = Geometry(0, 0, 1, 1)
g2 = Geometry(1, 0, 1, 1)

assert g1.directions_to(g2) == {Ordinal.EAST, Ordinal.EAST_NORTHEAST, Ordinal.EAST_SOUTHEAST}
assert list(g1.directions_to(g2)) == [Ordinal.EAST]

def test_directions_not_aligned(self):
"""
Expand All @@ -73,7 +28,7 @@ def test_directions_not_aligned(self):
g1 = Geometry(0, 0, 1, 1)
g2 = Geometry(1, 1, 1, 1)

assert g1.directions_to(g2) == {Ordinal.SOUTH_SOUTHEAST, Ordinal.SOUTHEAST, Ordinal.EAST_SOUTHEAST}
assert list(g1.directions_to(g2)) == [Ordinal.SOUTHEAST]

def test_directions_overlap(self):
"""
Expand All @@ -86,7 +41,32 @@ def test_directions_overlap(self):
g1 = Geometry(0, 0, 2, 2)
g2 = Geometry(2, 1, 2, 2)

assert g1.directions_to(g2) == {
Ordinal.EAST,
assert list(g1.directions_to(g2)) == [
Ordinal.EAST_SOUTHEAST,
}
Ordinal.SOUTHEAST,
]

def test_gleb_setup(self):
"""
https://github.com/AlexisBRENON/ewmh_m2m/pull/25
0 1080 3000
0 ┌─────────┐
130 ┌─────┤ │
│ │ g1 │
│ │ │
1080 │ g2 ├─────────┤
│ │ │
│ │ g3 │
2050 └─────┤ │
2160 └─────────┘
"""
g1 = Geometry(1080, 0, 1920, 1080)
g2 = Geometry(0, 130, 1080, 1920)
g3 = Geometry(1080, 1080, 1920, 1080)

assert list(g1.directions_to(g2)) == [Ordinal.WEST_SOUTHWEST, Ordinal.WEST]
assert list(g1.directions_to(g3)) == [Ordinal.SOUTH]
assert list(g2.directions_to(g1)) == [Ordinal.EAST_NORTHEAST, Ordinal.EAST]
assert list(g2.directions_to(g3)) == [Ordinal.EAST_SOUTHEAST, Ordinal.EAST]
assert list(g3.directions_to(g1)) == [Ordinal.NORTH]
assert list(g3.directions_to(g2)) == [Ordinal.WEST_NORTHWEST, Ordinal.WEST]
33 changes: 23 additions & 10 deletions tests/test_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,21 @@ def test_siblings_vertical(self):
assert siblings[Ordinal.NORTH] == [Geometry(0, 10, 10, 10), Geometry(0, 0, 10, 10)]

def test_siblings(self):
"""
0 1 2 3 4 5
0 ┌───┬───┬───┬───┬───┐
│ NW│NNW│ N │NNE│ NE│
1 ├───┼───┼───┼───┼───┤
│WNW│ NW│ N │ NE│ENE│
2 ├───┼───┼───┼───┼───┤
│ W │ W │ c │ E │ E │
3 ├───┼───┼───┼───┼───┤
│WSW│ SW│ S │ SE│ESE│
4 ├───┼───┼───┼───┼───┤
│ SW│SSW│ S │SSE│ SE│
5 └───┴───┴───┴───┴───┘
"""
screens = sorted(
[Geometry(x, y, 1, 1) for x in range(5) for y in range(5)],
key=lambda g: random.random())
Expand All @@ -68,16 +83,14 @@ def test_siblings(self):
assert siblings[Ordinal.SOUTHWEST] == [Geometry(1, 3, 1, 1), Geometry(1, 4, 1, 1), Geometry(0, 3, 1, 1), Geometry(0, 4, 1, 1)]
assert siblings[Ordinal.SOUTHEAST] == [Geometry(3, 3, 1, 1), Geometry(3, 4, 1, 1), Geometry(4, 3, 1, 1), Geometry(4, 4, 1, 1)]

assert set(siblings[Ordinal.EAST_NORTHEAST]) == set(siblings[Ordinal.EAST] + siblings[Ordinal.NORTHEAST])
assert set(siblings[Ordinal.NORTH_NORTHEAST]) == set(siblings[Ordinal.NORTH] + siblings[Ordinal.NORTHEAST])
assert set(siblings[Ordinal.NORTH_NORTHWEST]) == set(siblings[Ordinal.NORTH] + siblings[Ordinal.NORTHWEST])
assert set(siblings[Ordinal.WEST_NORTHWEST]) == set(siblings[Ordinal.WEST] + siblings[Ordinal.NORTHWEST])
assert set(siblings[Ordinal.WEST_SOUTHWEST]) == set(siblings[Ordinal.WEST] + siblings[Ordinal.SOUTHWEST])
assert set(siblings[Ordinal.SOUTH_SOUTHWEST]) == set(siblings[Ordinal.SOUTH] + siblings[Ordinal.SOUTHWEST])
assert set(siblings[Ordinal.SOUTH_SOUTHEAST]) == set(siblings[Ordinal.SOUTH] + siblings[Ordinal.SOUTHEAST])
assert set(siblings[Ordinal.EAST_SOUTHEAST]) == set(siblings[Ordinal.EAST] + siblings[Ordinal.SOUTHEAST])


assert siblings[Ordinal.EAST_NORTHEAST] == [Geometry(4, 1, 1, 1)]
assert siblings[Ordinal.NORTH_NORTHEAST] == [Geometry(3, 0, 1, 1)]
assert siblings[Ordinal.NORTH_NORTHWEST] == [Geometry(1, 0, 1, 1)]
assert siblings[Ordinal.WEST_NORTHWEST] == [Geometry(0, 1, 1, 1)]
assert siblings[Ordinal.WEST_SOUTHWEST] == [Geometry(0, 3, 1, 1)]
assert siblings[Ordinal.SOUTH_SOUTHWEST] == [Geometry(1, 4, 1, 1)]
assert siblings[Ordinal.SOUTH_SOUTHEAST] == [Geometry(3, 4, 1, 1)]
assert siblings[Ordinal.EAST_SOUTHEAST] == [Geometry(4, 3, 1, 1)]

def test_siblings_gh_issue_14(self):
"""
Expand Down

0 comments on commit 28f17ed

Please sign in to comment.