#ifndef _STOPTIFU_RECT3_H_ #define _STOPTIFU_RECT3_H_ typedef struct { int l0, l1, l2, h0, h1, h2; } rect3; /* extern rect3 rect3_compute_alpha(int n, const int *p, const int * const *v, const int * const *inv, int k, int **r, int dbg); */ #define rect3_copy(x) (x) TI_INLINE(rect3_intersection) rect3 rect3_intersection(rect3 r, rect3 s) { if (s.l0 > r.l0) r.l0 = s.l0; if (s.h0 < r.h0) r.h0 = s.h0; if (s.l1 > r.l1) r.l1 = s.l1; if (s.h1 < r.h1) r.h1 = s.h1; if (s.l2 > r.l2) r.l2 = s.l2; if (s.h2 < r.h2) r.h2 = s.h2; return r; } /* bounding box of union */ TI_INLINE(rect3_rect3_approximate_union) rect3 rect3_rect3_approximate_union(rect3 r, rect3 s) { if (s.l0 < r.l0) r.l0 = s.l0; if (s.h0 > r.h0) r.h0 = s.h0; if (s.l1 < r.l1) r.l1 = s.l1; if (s.h1 > r.h1) r.h1 = s.h1; if (s.l2 < r.l2) r.l2 = s.l2; if (s.h2 > r.h2) r.h2 = s.h2; return r; } TI_INLINE(rect3_is_empty) bool rect3_is_empty(rect3 r) { return ((r.l0 > r.h0) || (r.l1 > r.h1) || (r.l2 > r.h2)); } TI_INLINE(rect3_contains2) bool rect3_contains2(rect3 r, int x, int y) { return r.l0 <= x && x <= r.h0 && r.l1 <= y && y <= r.h1; } TI_INLINE(rect3_contains1) bool rect3_contains1(rect3 r, int x) { return r.l0 <= x && x <= r.h0; } TI_INLINE(rect3_to_ivseti) ivseti *rect3_to_ivseti(rect3 r) { if (rect3_is_empty(r)) return ivseti_emptyset(); return interval_cross_ivseti(make_iinterval(r.l0, r.h0), interval_cross_ivseti(make_iinterval(r.l1, r.h1), ivseti_single_interval(make_iinterval(r.l2, r.h2)))); } /* Return bounding box. */ TI_INLINE(ivseti_to_rect3) rect3 ivseti_to_rect3(ivseti *s) { rect3 result; ivseti_range(s, 0, &result.l0, &result.h0); ivseti_range(s, 1, &result.l1, &result.h1); ivseti_range(s, 2, &result.l2, &result.h2); return result; } TI_INLINE(ivseti_rect3_union) ivseti *ivseti_rect3_union(ivseti *r, rect3 s) { return ivseti_union(r, rect3_to_ivseti(s)); } TI_INLINE(ivseti_rect3_intersection) ivseti *ivseti_rect3_intersection(ivseti *r, rect3 s) { return ivseti_intersection(r, rect3_to_ivseti(s)); } /* bounding box of union */ TI_INLINE(rect3_ivseti_approximate_union) rect3 rect3_ivseti_approximate_union(rect3 r, ivseti *s) { return rect3_rect3_approximate_union(r, ivseti_to_rect3(s)); } /* is s shifted by some vector a subset of t? */ TI_INLINE(rect3_is_shifted_subset) bool rect3_is_shifted_subset(rect3 s, rect3 t, int d0, int d1, int d2) { return (range_superset(t.l0, t.h0, s.l0 + d0, s.h0 + d0) && range_superset(t.l1, t.h1, s.l1 + d1, s.h1 + d1) && range_superset(t.l2, t.h2, s.l2 + d2, s.h2 + d2)); } /* is s shifted by some vector a subset of t? */ TI_INLINE(rect3_ivseti_is_shifted_subset) bool rect3_ivseti_is_shifted_subset(rect3 s, ivseti *t, int d0, int d1, int d2) { return ivseti_is_shifted_subset3(rect3_to_ivseti(s), t, d0, d1, d2); } /* is s shifted by some vector a subset of t? */ TI_INLINE(ivseti_rect3_is_shifted_subset) bool ivseti_rect3_is_shifted_subset(ivseti *s, rect3 t, int d0, int d1, int d2) { return rect3_is_shifted_subset(ivseti_to_rect3(s), t, d0, d1, d2); } /* Caller should free the result. */ #define rect3_to_string_body \ { \ char *q = ALLOC(char, 300); \ sprintf(q, "{ (%d, %d, %d) - (%d, %d, %d) }", r.l0, r.l1, r.l2, \ r.h0, r.h1, r.h2); \ return q; \ } TI_INLINE(rect3_to_string) char *rect3_to_string(rect3 r) rect3_to_string_body #undef rect3_to_string_body #endif