"""Bounding-box math shared by grouping, tracking, capture, drawing.""" from __future__ import annotations import math from typing import Tuple Bbox = Tuple[int, int, int, int] def clamp_bbox(bbox: Bbox, w: int, h: int) -> Bbox: x1, y1, x2, y2 = bbox return max(0, x1), max(0, y1), min(w, x2), min(h, y2) def expand_bbox(bbox: Bbox, w: int, h: int, sx: float = 0.8, sy: float = 1.5) -> Bbox: x1, y1, x2, y2 = bbox bw, bh = x2 - x1, y2 - y1 cx, cy = (x1 + x2) // 2, (y1 + y2) // 2 nw, nh = int(bw * (1 + sx)), int(bh * (1 + sy)) nx1 = max(0, cx - nw // 2) ny1 = max(0, cy - nh // 2) return nx1, ny1, min(w, nx1 + nw), min(h, ny1 + nh) def merge_boxes(a: Bbox, b: Bbox) -> Bbox: return (min(a[0], b[0]), min(a[1], b[1]), max(a[2], b[2]), max(a[3], b[3])) def box_center(bbox: Bbox): return ((bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2) def box_distance(a: Bbox, b: Bbox) -> float: ca, cb = box_center(a), box_center(b) return math.hypot(ca[0] - cb[0], ca[1] - cb[1])