| 1 | use crate::geom::Rect; |
| 2 | |
| 3 | pub(crate) const LEFT: u8 = 1; |
| 4 | pub(crate) const RIGHT: u8 = 2; |
| 5 | pub(crate) const ABOVE: u8 = 4; |
| 6 | pub(crate) const BELOW: u8 = 8; |
| 7 | pub(crate) const X_BITS: u8 = LEFT | RIGHT; |
| 8 | pub(crate) const Y_BITS: u8 = ABOVE | BELOW; |
| 9 | |
| 10 | /// Which ways `a` is apart from `b`. Touching edges count as apart. |
| 11 | pub(crate) fn separation(a: &Rect, b: &Rect, eps: f64) -> u8 { |
| 12 | let mut s = 0; |
| 13 | if a.right() <= b.x + eps { |
| 14 | s |= LEFT; |
| 15 | } |
| 16 | if b.right() <= a.x + eps { |
| 17 | s |= RIGHT; |
| 18 | } |
| 19 | if a.bottom() <= b.y + eps { |
| 20 | s |= ABOVE; |
| 21 | } |
| 22 | if b.bottom() <= a.y + eps { |
| 23 | s |= BELOW; |
| 24 | } |
| 25 | s |
| 26 | } |
| 27 | |
| 28 | /// Which sides of `a` sit against `b`, at most one gap apart and facing each other. |
| 29 | pub(crate) fn adjacency(a: &Rect, b: &Rect, gap: f64, eps: f64) -> u8 { |
| 30 | let overlap_x = a.x < b.right() + eps && b.x < a.right() + eps; |
| 31 | let overlap_y = a.y < b.bottom() + eps && b.y < a.bottom() + eps; |
| 32 | let near = |d: f64| d.abs() <= gap + eps; |
| 33 | let mut s = 0; |
| 34 | if overlap_y && near(b.x - a.right()) { |
| 35 | s |= LEFT; |
| 36 | } |
| 37 | if overlap_y && near(a.x - b.right()) { |
| 38 | s |= RIGHT; |
| 39 | } |
| 40 | if overlap_x && near(b.y - a.bottom()) { |
| 41 | s |= ABOVE; |
| 42 | } |
| 43 | if overlap_x && near(a.y - b.bottom()) { |
| 44 | s |= BELOW; |
| 45 | } |
| 46 | s |
| 47 | } |