add intersection

This commit is contained in:
saji 2024-09-19 14:32:02 -05:00 committed by Saji
parent c6a81b5a76
commit 29464f91b4

View file

@ -3,6 +3,8 @@
from enum import Enum from enum import Enum
from dataclasses import dataclass from dataclasses import dataclass
from typing import Self
from math import ceil, log2
@dataclass(frozen=True, order=True) @dataclass(frozen=True, order=True)
@ -13,7 +15,7 @@ class Coord:
x: int x: int
y: int y: int
def __post_init__(self): def __post_init__(self):
if self.x < 0 or self.y < 0: if self.x < 0 or self.y < 0:
raise RuntimeError("x and y must both be >= 0") raise RuntimeError("x and y must both be >= 0")
@ -34,6 +36,26 @@ class BBox:
def contains(self, c: Coord) -> bool: def contains(self, c: Coord) -> bool:
return c > self.topleft and c < self.bottomright return c > self.topleft and c < self.bottomright
@property
def width(self) -> int:
return self.bottomright.x - self.topleft.x
@property
def height(self) -> int:
return self.bottomright.y - self.topleft.y
def intersects(self, other: Self) -> bool:
## other leftmost edge is right of our rightmost edge
x1 = other.topleft.x > self.bottomright.x
# our leftmost edge is to the right of other rightmost edge
x2 = self.topleft.x > other.bottomright.x
# other top edge is below (greater than!) our bottom edge
y1 = other.topleft.y > self.bottomright.y
# our top edge is below other bottom edge.
y2 = self.topleft.y > other.bottomright.y
return not (x1 or x2 or y1 or y2)
@dataclass(frozen=True) @dataclass(frozen=True)
class DisplayDimensions: class DisplayDimensions:
@ -44,6 +66,10 @@ class DisplayDimensions:
length: int length: int
height: int height: int
mux: int = 2 # number of lines driven at once.
def addr_bits(self) -> int:
return ceil(log2(self.height / self.mux))
class DisplayRotation(Enum): class DisplayRotation(Enum):
@ -68,7 +94,7 @@ class DisplayRotation(Enum):
@dataclass(frozen=True) @dataclass(frozen=True)
class _DisplayString: class DisplayString:
"""Internal class to represent a string of HUB75 displays. """Internal class to represent a string of HUB75 displays.
position: (X,Y) coordinates of the local top-left of the display position: (X,Y) coordinates of the local top-left of the display
@ -81,6 +107,7 @@ class _DisplayString:
position: Coord position: Coord
dimensions: DisplayDimensions dimensions: DisplayDimensions
rotation: DisplayRotation rotation: DisplayRotation
# TODO: encode muxing
@property @property
def bbox(self) -> BBox: def bbox(self) -> BBox:
@ -103,10 +130,13 @@ class _DisplayString:
"""Checks if the given coordinate is inside this display.""" """Checks if the given coordinate is inside this display."""
return self.bbox.contains(coord) return self.bbox.contains(coord)
def intersects(self, box: BBox) -> bool:
"""Checks if the given BBox intersects with this display"""
return self.bbox.intersects(box)
class DisplayGeometry: class DisplayGeometry:
"""Represents a display based on several strings in different positions. """Represents a display based on several strings in different positions."""
"""
def __init__(self, *, strict: bool = False): def __init__(self, *, strict: bool = False):
self.strict = strict self.strict = strict