38 lines
1.0 KiB
Python
38 lines
1.0 KiB
Python
"""Nearest-match selection of a catalog record for a knob coordinate."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import math
|
|
from dataclasses import dataclass
|
|
|
|
from hef.catalog import Record
|
|
|
|
SELECTOR_MODES = frozenset({"none", "audio", "video", "av"})
|
|
CONTENT_MODES = frozenset({"audio", "video", "av"})
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Coordinate:
|
|
left: int
|
|
right: int
|
|
dark: int
|
|
light: int
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Weights:
|
|
brain: float = 1.0
|
|
mood: float = 1.0
|
|
|
|
|
|
def distance(a: Coordinate, b: Coordinate, weights: Weights = Weights()) -> float:
|
|
"""Weighted Euclidean distance; brain plane and mood plane weighted separately."""
|
|
brain_sq = (a.left - b.left) ** 2 + (a.right - b.right) ** 2
|
|
mood_sq = (a.dark - b.dark) ** 2 + (a.light - b.light) ** 2
|
|
return math.sqrt(weights.brain * brain_sq + weights.mood * mood_sq)
|
|
|
|
|
|
def record_coordinate(record: Record) -> Coordinate:
|
|
"""The (left, right, dark, light) coordinate of a catalog record."""
|
|
return Coordinate(record.left, record.right, record.dark, record.light)
|