int rectangle_intersection(const point &a1, const point &b1, const point &a2, const point &b2, point *p = NULL, point *q = NULL) { bool a1in2 = point_in_rectangle(a1, a2, b2); bool b1in2 = point_in_rectangle(b1, a2, b2); if (a1in2 && b1in2) { if (p != NULL && q != NULL) { *p = std::min(a1, b1); *q = std::max(a1, b1); } return 1; // Rectangle 1 completely inside 2. } if (!a1in2 && !b1in2) { if (point_in_rectangle(a2, a1, b1)) { if (p != NULL && q != NULL) { *p = std::min(a2, b2); *q = std::max(a2, b2); } return 2; // Rectangle 2 completely inside 1. } return -1; // Completely disjoint. } if (p != NULL && q != NULL) { if (a1in2) { *p = a1; *q = (a1 < b1) ? std::max(a2, b2) : std::min(a2, b2); } else { *p = b1; *q = (b1 < a1) ? std::max(a2, b2) : std::min(a2, b2); } if (*p > *q) { std::swap(p, q); } } return 0; }
bool point_in_rectangle(const point &p, const point &v, double w, double h) { static const bool EDGE_IS_INSIDE = true; if (w < 0) { return point_in_rectangle(p, point(v.x + w, v.y), -w, h); } if (h < 0) { return point_in_rectangle(p, point(v.x, v.y + h), w, -h); } return EDGE_IS_INSIDE ? (GE(p.x, v.x) && LE(p.x, v.x + w) && GE(p.y, v.y) && LE(p.y, v.y + h)) : (GT(p.x, v.x) && LT(p.x, v.x + w) && GT(p.y, v.y) && LT(p.y, v.y + h)); }
int collide_polygon_rectangle(int n, int *xs, int *ys, int rx, int ry, int w, int h) { assert(n > 0); int polygon_line[2][2]; int rectangle_lines[4][2][2] = { { {rx, ry}, {rx+w, ry} }, { {rx+w, ry}, {rx+w, ry+h} }, { {rx+w, ry+h}, {rx, ry+h} }, { {rx, ry+h}, {rx, ry} } }; int polygon_index, rectangle_index; int old_polygon_index = n - 1; for (polygon_index = 0; polygon_index < n; ++polygon_index) { polygon_line[0][0] = xs[old_polygon_index]; polygon_line[0][1] = ys[old_polygon_index]; polygon_line[1][0] = xs[polygon_index]; polygon_line[1][1] = ys[polygon_index]; for (rectangle_index = 0; rectangle_index < 4; ++rectangle_index) { if (lines_intersect(polygon_line, rectangle_lines[rectangle_index])) { return COLLISION; } } old_polygon_index = polygon_index; } if (point_in_rectangle(xs[0], ys[0], rx, ry, w, h)) { return COLLISION; } if (point_in_polygon(rx, ry, n, xs, ys)) { return COLLISION; } return NO_COLLISION; }
int main() { assert(EQ(20, rectangle_area(point(1, 1), point(5, 6)))); assert(point_in_rectangle(point(0, -1), point(0, -3), 3, 2)); assert(point_in_rectangle(point(2, -2), point(3, -3), -3, 2)); assert(!point_in_rectangle(point(0, 0), point(3, -1), -3, -2)); assert(point_in_rectangle(point(2, -2), point(3, -3), point(0, -1))); assert(!point_in_rectangle(point(-1, -2), point(3, -3), point(0, -1))); point p, q; assert(-1 == rectangle_intersection(point(0, 0), point(1, 1), point(2, 2), point(3, 3))); assert(0 == rectangle_intersection(point(1, 1), point(7, 7), point(5, 5), point(0, 0), &p, &q)); assert(EQP(p, point(1, 1)) && EQP(q, point(5, 5))); assert(1 == rectangle_intersection(point(1, 1), point(0, 0), point(0, 0), point(1, 10), &p, &q)); assert(EQP(p, point(0, 0)) && EQP(q, point(1, 1))); assert(2 == rectangle_intersection(point(0, 5), point(5, 7), point(1, 6), point(2, 5), &p, &q)); assert(EQP(p, point(1, 6)) && EQP(q, point(2, 5))); return 0; }
bool move_player(Player& player, short direction, Rectangle& area) { Point offset = get_offset(direction); // No attempt? if(offset.x == 0 && offset.y == 0) { return false; } Point target = sum_points(player, offset); // Out of bounds? if(!point_in_rectangle(target, area)) { return false; } // Blocked? // if(!is_open_cell(area, target)) { // return false; // } player.x = target.x; player.y = target.y; return true; }
void widget::process_event(const event& ev) { switch (ev.type) { case event::mouse_move_abs: { bool inside (point_in_rectangle(ev.xy, bounding_rect())); if (inside != mouse_inside_flag_) { if (inside) on_mouse_enter(); else on_mouse_leave(); mouse_inside_flag_ = inside; } } break; default: ; } }
bool point_in_rectangle(const point &p, const point &a, const point &b) { double xl = std::min(a.x, b.x), yl = std::min(a.y, b.y); double xh = std::max(a.x, b.x), yh = std::max(a.y, b.y); return point_in_rectangle(p, point(xl, yl), xh - xl, yh - yl); }