atagen

monolith

public
Star0
Watch0
8ffa3fa4d4a9331f2638c1598a9f3c107e148296
1
ssh://brewery@pls.lobotomise.me:33/atagen/monolith.git
crates/planner/src/relation.rsRust47 lines1.3 KB
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
}